Integre recursos OpenAI, Comunicação e Dados Organizacionais em um aplicativo de linha de negócios
Nível: intermediário
Este tutorial demonstra como o Azure OpenAI, os Serviços de Comunicação do Azure e o Microsoft Graph/Microsoft Graph Toolkit podem ser integrados a um aplicativo LOB (Linha de Negócios) para aumentar a produtividade do usuário, elevar a experiência do usuário e levar os aplicativos LOB para o próximo nível. Os principais recursos do aplicativo incluem:
- IA: permita que os usuários façam perguntas em linguagem natural e convertam suas respostas em SQL que podem ser usadas para consultar um banco de dados, permita que os usuários definam regras que podem ser usadas para gerar automaticamente mensagens de email e SMS e aprendam como a linguagem natural pode ser usada para recuperar dados de suas próprias fontes de dados personalizadas. O Azure OpenAI é usado para esses recursos.
- Comunicação: habilite chamadas telefônicas no aplicativo para clientes e funcionalidade de email/SMS usando os Serviços de Comunicação do Azure.
- Dados organizacionais: extraia dados organizacionais relacionados que os usuários podem precisar (documentos, chats, emails, eventos de calendário) enquanto trabalham com os clientes para evitar a alternância de contexto. Fornecer acesso a esse tipo de dados organizacionais reduz a necessidade de o usuário alternar para Outlook, Teams, OneDrive, outros aplicativos personalizados, seu telefone etc., pois os dados e funcionalidades específicos de que precisam são fornecidos diretamente no aplicativo. O Microsoft Graph e o Microsoft Graph Toolkit são usados para esse recurso.
O aplicativo é um aplicativo simples de gerenciamento de clientes que permite aos usuários gerenciar seus clientes e dados relacionados. Ele consiste em um front-end criado usando TypeScript que chama APIs de back-end para recuperar dados, interagir com a funcionalidade de IA, enviar mensagens de e-mail/SMS e extrair dados organizacionais. Aqui está uma visão geral da solução de aplicativo que você abordará neste tutorial:
O tutorial orientará você pelo processo de configuração dos recursos necessários do Azure e do Microsoft 365. Ele também orientará você pelo código usado para implementar os recursos de IA, comunicação e dados organizacionais. Embora você não precise copiar e colar código, alguns dos exercícios farão com que você modifique o código para experimentar diferentes cenários.
O que você criará neste tutorial
Escolha sua própria aventura
Você pode concluir todo o tutorial do início ao fim ou concluir tópicos específicos de interesse. O tutorial é dividido nos seguintes tópicos:
- Clone o Exercício do Projeto (exercício obrigatório).
- Exercícios de IA: crie um recurso OpenAI do Azure e use-o para converter linguagem natural em SQL, gerar mensagens de email/SMS e trabalhar com seus próprios dados e documentos.
- Exercícios de comunicação: crie um recurso dos Serviços de Comunicação do Azure e use-o para fazer chamadas telefônicas do aplicativo e enviar mensagens de email/SMS.
- Exercícios de dados organizacionais: crie um registro de aplicativo de ID do Microsoft Entra para que o Microsoft Graph e o Microsoft Graph Toolkit possam ser usados para autenticar e extrair dados organizacionais para o aplicativo.
Pré-requisitos
- Nó - O nó 20+ e o npm 10+ serão usados para este projeto
- git
- Visual Studio Code (embora o Visual Studio Code seja recomendado, qualquer editor pode ser usado)
- Assinatura do Azure
- Locatário do desenvolvedor do Microsoft 365
- Docker Desktop ou outro runtime de contêiner compatível com OCI (Open Container Initiative), como Podman, ou nerdctl capaz de executar um contêiner.
Tecnologias de nuvem da Microsoft usadas neste tutorial
- Serviços de Comunicação do Azure
- Serviço OpenAI do Azure
- ID do Microsoft Entra
- Microsoft Graph
- Kit de Ferramentas do Microsoft Graph
Clonar o projeto
O projeto de código usado neste tutorial está disponível em https://github.com/microsoft/MicrosoftCloud. O repositório do projeto inclui o código do lado do cliente e do lado do servidor necessário para executar o projeto, permitindo que você explore os recursos integrados relacionados à inteligência artificial (IA), comunicação e dados organizacionais. Além disso, o projeto serve como recurso para orientá-lo na incorporação de recursos semelhantes em seus próprios aplicativos.
Neste exercício, você vai:
- Clone o repositório do GitHub.
- Adicione um arquivo .env ao projeto e atualize-o.
Antes de continuar, verifique se você tem todos os pré-requisitos instalados e configurados conforme descrito na seção Pré-requisitos deste tutorial.
Clonar o repositório GitHub e criar um .env
arquivo
Execute o comando a seguir para clonar o Repositório GitHub do Microsoft Cloud em seu computador.
git clone https://github.com/microsoft/MicrosoftCloud
Abra a pasta MicrosoftCloud/samples/openai-acs-msgraph no Visual Studio Code.
Observação
Embora usemos o Visual Studio Code ao longo deste tutorial, qualquer editor de código pode ser usado para trabalhar com o projeto de exemplo.
Observe as seguintes pastas e arquivos:
- client: Código do aplicativo do lado do cliente.
- server: código de API do lado do servidor.
- docker-compose.yml: Usado para executar um banco de dados PostgreSQL local.
Renomeie o .env.example na raiz do projeto para .env.
Abra o arquivo .env e reserve um momento para examinar as chaves incluídas:
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=
Atualize os seguintes valores em .env. Esses valores serão usados pelo servidor de API para se conectar ao banco de dados PostgreSQL local.
POSTGRES_USER=web POSTGRES_PASSWORD=web-password
Agora que você tem o projeto em vigor, vamos experimentar alguns dos recursos do aplicativo e aprender como eles são criados. Selecione o botão Avançar abaixo para continuar ou pular para um exercício específico usando o índice.
IA: criar um recurso OpenAI do Azure e implantar um modelo
Para começar a usar o Azure OpenAI em seus aplicativos, você precisa criar um Serviço OpenAI do Azure e implantar um modelo que possa ser usado para executar tarefas como converter linguagem natural em SQL, gerar conteúdo de mensagem de email/SMS e muito mais.
Neste exercício, você vai:
- Crie um recurso do Serviço OpenAI do Azure.
- Implantar um modelo.
- Atualize o arquivo .env com valores do recurso de serviço OpenAI do Azure.
Criar um recurso de serviço OpenAI do Azure
Visite o portal do Azure em seu navegador e entre.
Insira openai na barra de pesquisa na parte superior da página do portal e selecione Azure OpenAI nas opções exibidas.
Selecione Criar na barra de ferramentas.
Observação
Embora este tutorial se concentre no Azure OpenAI, se você tiver uma chave de API do OpenAI e quiser usá-la, ignore esta seção e vá diretamente para a seção Atualizar o arquivo .env do projeto abaixo. Atribua sua chave de API OpenAI no
OPENAI_API_KEY
arquivo .env (você pode ignorar quaisquer outras.env
instruções relacionadas ao OpenAI).Os modelos OpenAI do Azure estão disponíveis em regiões específicas. Visite o documento de disponibilidade do modelo OpenAI do Azure para saber quais regiões dão suporte ao modelo gpt-4o usado neste tutorial.
Execute as seguintes tarefas:
- Selecione sua assinatura do Azure.
- Selecione o grupo de recursos a ser usado (crie um novo, se necessário).
- Selecione uma região onde o modelo gpt-4o é suportado com base no documento que você examinou anteriormente.
- Insira o nome do recurso. Ele precisa ser um valor exclusivo.
- Selecione o tipo de preço Standard S0 .
Selecione Avançar até chegar à tela Revisar + enviar . Selecione Criar.
Depois que o recurso OpenAI do Azure for criado, navegue até ele e selecione Gerenciamento de Recursos -->Chaves e Ponto de Extremidade.
Localize os valores KEY 1 e Endpoint . Você usará os dois valores na próxima seção, portanto, copie-os para um arquivo local.
Selecione Gerenciamento de Recursos -->Modelar implantações.
Selecione o botão Gerenciar Implantações para acessar o Azure OpenAI Studio.
Selecione Implantar modelo -->Implantar modelo base na barra de ferramentas.
Selecione gpt-4o na lista de modelos e selecione Confirmar.
Observação
O OpenAI do Azure dá suporte a vários tipos diferentes de modelos. Cada modelo pode ser usado para lidar com diferentes cenários.
A caixa de diálogo a seguir será exibida. Reserve um momento para examinar os valores padrão fornecidos.
Altere o valor do Limite de Taxa de Tokens por Minuto (milhares) para 100K. Isso permitirá que você faça mais solicitações ao modelo e evite atingir o limite de taxa ao executar as etapas a seguir.
Selecione Implantar.
Depois que o modelo for implantado, selecione Playgrounds -->Chat.
O menu suspenso Implantação deve exibir o modelo gpt-4o .
Reserve um momento para ler o texto da mensagem do sistema fornecido. Isso informa ao modelo como agir à medida que o usuário interage com ele.
Localize a caixa de texto na área de bate-papo e digite Resumir o que é IA generativa e como ela pode ser usada. Selecione Enter para enviar a mensagem ao modelo e fazer com que ele gere uma resposta.
Experimente outros prompts e respostas. Por exemplo, insira Fornecer um breve histórico sobre a capital da França e observe a resposta gerada.
Atualizar o arquivo do .env
projeto
Volte para o Visual Studio Code e abra o
.env
arquivo na raiz do projeto.Copie o valor KEY 1 do recurso OpenAI do Azure e atribua-o no
OPENAI_API_KEY
arquivo .env localizado na raiz da pasta openai-acs-msgraph:OPENAI_API_KEY=<KEY_1_VALUE>
Copie o valor *Endpoint e atribua-o no
OPENAI_ENDPOINT
arquivo .env. Remova o/
caractere do final do valor, se ele estiver presente.OPENAI_ENDPOINT=<ENDPOINT_VALUE>
Observação
Você verá que os valores e
OPENAI_MODEL
OPENAI_API_VERSION
já estão definidos no arquivo .env . O valor do modelo é definido como gpt-4o, que corresponde ao nome de implantação do modelo criado anteriormente neste exercício. A versão da API é definida como um valor com suporte definido na documentação de referência do OpenAI do Azure.Salve o arquivo .env.
Inicie os serviços de aplicativos
É hora de iniciar seus serviços de aplicativos, incluindo o banco de dados, o servidor de API e o servidor web.
Nas etapas a seguir, você criará três janelas de terminal no Visual Studio Code.
Clique com o botão direito do mouse no arquivo .env na lista de arquivos do Visual Studio Code e selecione Abrir no Terminal Integrado. Certifique-se de que seu terminal esteja na raiz do projeto - openai-acs-msgraph - antes de continuar.
Escolha uma das seguintes opções para iniciar o banco de dados PostgreSQL:
Se você tiver o Docker Desktop instalado e em execução, execute
docker-compose up
na janela do terminal e pressione Enter.Se você tiver o Podman com o podman-compose instalado e em execução, execute
podman-compose up
na janela do terminal e pressione Enter.Para executar o contêiner do PostgreSQL diretamente usando o Docker Desktop, o Podman, o nerdctl ou outro tempo de execução do contêiner que você instalou, execute o seguinte comando na janela do terminal:
Subsistema Mac, Linux ou 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 com 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
Depois que o contêiner do banco de dados for iniciado, pressione o + ícone na barra de ferramentas do Terminal do Visual Studio Code para criar uma segunda janela de terminal.
cd
na pasta server/typescript e execute os comandos a seguir para instalar as dependências e iniciar o servidor de API.npm install
npm start
Pressione o + ícone novamente na barra de ferramentas do Terminal do Visual Studio Code para criar uma terceira janela de terminal.
cd
na pasta do cliente e execute os comandos a seguir para instalar as dependências e iniciar o servidor Web.npm install
npm start
Um navegador será iniciado e você será direcionado para http://localhost:4200.
IA: Linguagem Natural para SQL
A citação "Só porque você pode, não significa que deveria" é um guia útil ao pensar em recursos de IA. Por exemplo, o recurso de linguagem natural para SQL do Azure OpenAI permite que os usuários façam consultas ao banco de dados em inglês simples, o que pode ser uma ferramenta poderosa para aumentar sua produtividade. No entanto, poderoso nem sempre significa apropriado ou seguro. Este exercício demonstrará como usar esse recurso de IA e, ao mesmo tempo, discutirá considerações importantes a serem lembradas antes de decidir implementá-lo.
Aqui está um exemplo de uma consulta de linguagem natural que pode ser usada para recuperar dados de um banco de dados:
Get the the total revenue for all companies in London.
Com os prompts adequados, o Azure OpenAI converterá essa consulta em SQL que pode ser usada para retornar resultados do banco de dados. Como resultado, usuários não técnicos, incluindo analistas de negócios, profissionais de marketing e executivos, podem recuperar mais facilmente informações valiosas de bancos de dados sem lidar com a sintaxe SQL complexa ou depender de grades de dados e filtros restritos. Essa abordagem simplificada pode aumentar a produtividade, eliminando a necessidade de os usuários buscarem assistência de especialistas técnicos.
Este exercício fornece um ponto de partida que ajudará você a entender como funciona a linguagem natural para SQL, apresentará algumas considerações importantes, fará você pensar sobre prós e contras e mostrará o código para começar.
Neste exercício, você vai:
- Use prompts da GPT para converter linguagem natural em SQL.
- Experimente diferentes prompts da GPT.
- Use o SQL gerado para consultar o banco de dados PostgreSQL iniciado anteriormente.
- Retorne os resultados da consulta do PostgreSQL e exiba-os no navegador.
Vamos começar experimentando diferentes prompts GPT que podem ser usados para converter linguagem natural em SQL.
Usando o recurso de linguagem natural para SQL
No exercício anterior, você iniciou o banco de dados, as APIs e o aplicativo. Você também atualizou o
.env
arquivo. Se você não concluiu essas etapas, siga as instruções no final do exercício antes de continuar.Volte para o navegador (http://localhost:4200) e localize a seção Consulta personalizada da página abaixo da grade de dados. Observe que um valor de consulta de exemplo já está incluído: Obtenha a receita total de todos os pedidos. Agrupe por empresa e inclua a cidade.
Selecione o botão Executar Consulta. Isso passará a consulta de linguagem natural do usuário para o Azure OpenAI, que a converterá em SQL. A consulta SQL será usada para consultar o banco de dados e retornar possíveis resultados.
Execute a seguinte consulta personalizada:
Get the total revenue for Adventure Works Cycles. Include the contact information as well.
Exiba a janela de terminal que executa o servidor de API no Visual Studio Code e observe que ela exibe a consulta SQL retornada do Azure OpenAI. Os dados JSON são usados pelas APIs do lado do servidor para consultar o banco de dados PostgreSQL. Todos os valores de cadeia de caracteres incluídos na consulta são adicionados como valores de parâmetro para evitar ataques de injeção de 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"] }
Volte para o navegador e selecione Redefinir Dados para exibir todos os clientes novamente na grade de dados.
Explorando a linguagem natural para o código SQL
Dica
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Observação
O objetivo deste exercício é mostrar o que é possível com a funcionalidade de linguagem natural para SQL e demonstrar como começar a usá-la. Como mencionado anteriormente, é importante discutir se esse tipo de IA é apropriado para sua organização antes de prosseguir com qualquer implementação. Também é imperativo planejar regras de prompt adequadas e medidas de segurança de banco de dados para impedir o acesso não autorizado e proteger dados confidenciais.
Agora que você viu o recurso de linguagem natural para SQL em ação, vamos examinar como ele é implementado.
Abra o arquivo servidor/apiRoutes.ts e localize a
generateSql
rota. Essa rota de API é chamada pelo aplicativo do lado do cliente em execução no navegador e usada para gerar SQL a partir de uma consulta de linguagem natural. Depois que a consulta SQL é recuperada, ela é usada para consultar o banco de dados e retornar 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 a seguinte funcionalidade na
generateSql
rota:- Ele recupera o valor de consulta do
req.body.prompt
usuário e o atribui a uma variável chamadauserPrompt
. Esse valor será usado no prompt da GPT. - Ele chama uma
getSQLFromNLP()
função para converter linguagem natural em SQL. - Ele passa o SQL gerado para uma função chamada
queryDb
que executa a consulta SQL e retorna resultados do banco de dados.
- Ele recupera o valor de consulta do
Abra o arquivo de servidor/openAI.ts em seu editor e localize a
getSQLFromNLP()
função. Essa função é chamada pelageneratesql
rota e é usada para converter linguagem natural em 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; }
- Um
userPrompt
parâmetro é passado para a função. OuserPrompt
valor é a consulta de linguagem natural inserida pelo usuário no navegador. - A
systemPrompt
define o tipo de assistente de IA a ser usado e as regras que devem ser seguidas. Isso ajuda o Azure OpenAI a entender a estrutura do banco de dados, quais regras aplicar e como retornar a consulta SQL e os parâmetros gerados. - Uma função chamada
callOpenAI()
é chamada e ossystemPrompt
valores euserPrompt
são passados para ela. - Os resultados são verificados para garantir que nenhum valor proibido seja incluído na consulta SQL gerada. Se valores proibidos forem encontrados, a consulta SQL será definida como uma cadeia de caracteres vazia.
- Um
Vamos examinar o prompt do sistema com mais detalhes:
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"] } `;
O tipo de assistente de IA a ser usado é definido. Neste caso, um "bot de linguagem natural para SQL".
Os nomes das tabelas e as colunas no banco de dados são definidos. O esquema de alto nível incluído no prompt pode ser encontrado no arquivo server/db.schema e se parece com o seguinte.
- 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)
Dica
Você pode considerar a criação de exibições somente leitura que contenham apenas os dados que os usuários têm permissão para consultar usando linguagem natural para SQL.
Uma regra é definida para converter quaisquer valores de cadeia de caracteres em um valor de consulta parametrizado para evitar ataques de injeção de SQL.
Uma regra é definida para sempre retornar um objeto JSON com a consulta SQL e os valores de parâmetro nele.
Exemplos de prompts de usuário e os valores esperados de consulta SQL e parâmetro são fornecidos. Isso é conhecido como aprendizado de "poucos tiros". Embora os LLMs sejam treinados em grandes quantidades de dados, eles podem ser adaptados a novas tarefas com apenas alguns exemplos. Uma abordagem alternativa é o aprendizado "zero-shot", em que nenhum exemplo é fornecido e espera-se que o modelo gere os valores corretos de consulta SQL e parâmetro.
A
getSQLFromNLP()
função envia os prompts do sistema e do usuário para uma função chamadacallOpenAI()
que também está localizada no arquivo server/openAI.ts . AcallOpenAI()
função determina se o serviço OpenAI do Azure ou o serviço OpenAI deve ser chamado verificando as variáveis de ambiente. Se uma chave, um ponto de extremidade e um modelo estiverem disponíveis nas variáveis de ambiente, o OpenAI do Azure será chamado, caso contrário, o OpenAI será chamado.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); }
Observação
Embora nos concentremos no OpenAI do Azure ao longo deste tutorial, se você fornecer apenas um
OPENAI_API_KEY
valor no arquivo .env, o aplicativo usará o OpenAI. Se você optar por usar o OpenAI em vez do Azure OpenAI, poderá ver resultados diferentes em alguns casos.Localize a
getAzureOpenAICompletion()
função.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; }
Essa função faz o seguinte:
Parâmetros:
systemPrompt
,userPrompt
etemperature
são os principais parâmetros.systemPrompt
: informa o modelo OpenAI do Azure sobre sua função e as regras a serem seguidas.userPrompt
: Contém as informações fornecidas pelo usuário, como entrada de linguagem natural ou regras para gerar a saída.temperature
: Dita o nível de criatividade da resposta do modelo. Um valor mais alto resulta em mais resultados criativos.
Geração de conclusão:
- A função chama
createAzureOpenAICompletion()
comsystemPrompt
,userPrompt
, etemperature
para gerar uma conclusão. - Ele extrai o conteúdo da primeira escolha na conclusão, cortando qualquer espaço em branco extra.
- Se o conteúdo contiver estruturas semelhantes a JSON (indicadas pela presença de
{
e}
), ele extrairá o conteúdo JSON.
- A função chama
Registro em log e valor retornado:
- A função registra a saída do OpenAI do Azure no console.
- Ele retorna o conteúdo processado como uma cadeia de caracteres.
Localize a
createAzureOpenAICompletion()
função.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.`); } } }
Essa função faz o seguinte:
Parâmetros:
systemPrompt
,userPrompt
etemperature
são os principais parâmetros discutidos anteriormente.- Um parâmetro opcional
dataSources
dá suporte ao recurso "Azure Bring Your Own Data", que será abordado posteriormente neste tutorial.
Verificação de variáveis de ambiente:
- A função verifica a presença de variáveis de ambiente essenciais, gerando um erro se alguma estiver faltando.
Objeto de configuração:
- Um
config
objeto é criado usando valores do.env
arquivo (OPENAI_API_KEY
,OPENAI_ENDPOINT
,OPENAI_API_VERSION
,OPENAI_MODEL
). Esses valores são usados para construir a URL para chamar o Azure OpenAI.
- Um
Instância do AzureOpenAI:
- Uma instância de
AzureOpenAI
é criada usando o objetoconfig
. OAzureOpenAI
símbolo faz parte doopenai
pacote, que deve ser importado na parte superior do seu arquivo.
- Uma instância de
Gerando uma conclusão:
- A
chat.completions.create()
função é chamada com as seguintes propriedades:model
: Especifica o modelo GPT (por exemplo, gpt-4o, gpt-3.5-turbo) conforme definido em seu.env
arquivo.max_tokens
: Define o número máximo de tokens para a conclusão.temperature
: Define a temperatura de amostragem. Valores mais altos (por exemplo, 0,9) produzem respostas mais criativas, enquanto valores mais baixos (por exemplo, 0) produzem respostas mais determinísticas.response_format
: Define o formato da resposta. Aqui, ele está definido para retornar um objeto JSON. Mais detalhes sobre o modo JSON podem ser encontrados na documentação de referência do OpenAI do Azure.messages
: contém as mensagens para gerar conclusões de bate-papo. Este exemplo inclui duas mensagens: uma do sistema (definindo comportamento e regras) e outra do usuário (contendo o texto do prompt).
- A
Valor de retorno:
- A função retorna o objeto de conclusão gerado pelo OpenAI do Azure.
Comente as seguintes linhas na
getSQLFromNLP()
função:// if (isProhibitedQuery(queryData.sql)) { // queryData.sql = ''; // }
Economize openAI.ts. O servidor de API recompilará automaticamente o código TypeScript e reiniciará o servidor.
Volte para o navegador e insira Selecionar todos os nomes de tabela do banco de dados na entrada Consulta Personalizada . Selecione Executar Consulta. Os nomes das tabelas são exibidos?
Volte para a
getSQLFromNLP()
função no servidor/openAI.ts e adicione a seguinte regra naRules:
seção do prompt do sistema e salve o arquivo.- Do not allow the SELECT query to return table names, function names, or procedure names.
Volte para o navegador e execute as seguintes tarefas:
- Insira Selecione todos os nomes de tabela do banco de dados na entrada Consulta Personalizada . Selecione Executar Consulta. Os nomes das tabelas são exibidos?
- Insira Selecionar todos os nomes de função do banco de dados. na entrada Consulta personalizada e selecione Executar consulta novamente. Os nomes das funções são exibidos?
PERGUNTA: Um modelo sempre seguirá as regras definidas no prompt?
RESPOSTA: Não! É importante observar que os modelos OpenAI podem retornar resultados inesperados ocasionalmente que podem não corresponder às regras que você definiu. É importante planejar isso em seu código.
Volte para servidor /openAI.ts e localize a
isProhibitedQuery()
função. Este é um exemplo de código de pós-processamento que pode ser executado depois que o Azure OpenAI retorna resultados. Observe que ele define asql
propriedade como uma cadeia de caracteres vazia se palavras-chave proibidas forem retornadas na consulta SQL gerada. Isso garante que, se resultados inesperados forem retornados do Azure OpenAI, a consulta SQL não será executada no banco de dados.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)); }
Observação
É importante observar que este é apenas um código de demonstração. Pode haver outras palavras-chave proibidas necessárias para cobrir seus casos de uso específicos se você optar por converter linguagem natural em SQL. Esse é um recurso que você deve planejar e usar com cuidado para garantir que apenas consultas SQL válidas sejam retornadas e executadas no banco de dados. Além das palavras-chave proibidas, você também precisará levar em consideração a segurança.
Volte para server/openAI.ts e remova o comentário do código a seguir na
getSQLFromNLP()
função. Salve o arquivo.if (isProhibitedQuery(queryData.sql)) { queryData.sql = ''; }
Remova a regra a
systemPrompt
seguir e salve o arquivo.- Do not allow the SELECT query to return table names, function names, or procedure names.
Volte para o navegador, insira Selecionar todos os nomes de tabela do banco de dados na entrada Consulta personalizada novamente e selecione o botão Executar consulta .
Algum resultado da tabela é exibido? Mesmo sem a regra em vigor, o
isProhibitedQuery()
código de pós-processamento proíbe que esse tipo de consulta seja executado no banco de dados.Conforme discutido anteriormente, a integração da linguagem natural ao SQL em aplicativos de linha de negócios pode ser bastante benéfica para os usuários, mas vem com seu próprio conjunto de considerações.
Vantagens:
Facilidade de uso: esse recurso pode tornar a interação com o banco de dados mais acessível a usuários sem conhecimento técnico, reduzindo a necessidade de conhecimento de SQL e potencialmente acelerando as operações.
Maior produtividade: analistas de negócios, profissionais de marketing, executivos e outros usuários não técnicos podem recuperar informações valiosas de bancos de dados sem precisar depender de especialistas técnicos, aumentando assim a eficiência.
Ampla aplicação: usando modelos de linguagem avançados, os aplicativos podem ser projetados para atender a uma ampla gama de usuários e casos de uso.
Considerações:
Segurança: Uma das maiores preocupações é a segurança. Se os usuários podem interagir com bancos de dados usando linguagem natural, é necessário que haja medidas de segurança robustas para evitar acesso não autorizado ou consultas maliciosas. Você pode considerar a implementação de um modo somente leitura para impedir que os usuários modifiquem dados.
Privacidade de dados: Certos dados podem ser confidenciais e não devem ser facilmente acessíveis, portanto, você precisará garantir que as proteções adequadas e as permissões do usuário estejam em vigor.
Precisão: Embora o processamento de linguagem natural tenha melhorado significativamente, ele não é perfeito. A interpretação incorreta das consultas do usuário pode levar a resultados imprecisos ou comportamento inesperado. Você precisará planejar como os resultados inesperados serão tratados.
Eficiência: não há garantias de que o SQL retornado de uma consulta de linguagem natural será eficiente. Em alguns casos, chamadas adicionais para o Azure OpenAI podem ser necessárias se as regras de pós-processamento detectarem problemas com consultas SQL.
Treinamento e adaptação do usuário: Os usuários precisam ser treinados para formular suas consultas corretamente. Embora seja mais fácil do que aprender SQL, ainda pode haver uma curva de aprendizado envolvida.
Alguns pontos finais a serem considerados antes de passar para o próximo exercício:
- Lembre-se de que "Só porque você pode, não significa que você deve" se aplica aqui. Tenha muito cuidado e planejamento cuidadoso antes de integrar a linguagem natural ao SQL em um aplicativo. É importante entender os riscos potenciais e se planejar para eles.
- Antes de usar esse tipo de tecnologia, discuta possíveis cenários com sua equipe, administradores de banco de dados, equipe de segurança, partes interessadas e quaisquer outras partes relevantes para garantir que seja apropriado para sua organização. É importante discutir se a linguagem natural para SQL atende aos requisitos de segurança, privacidade e quaisquer outros requisitos que sua organização possa ter.
- A segurança deve ser uma preocupação principal e incorporada ao processo de planejamento, desenvolvimento e implantação.
- Embora a linguagem natural para SQL possa ser muito poderosa, um planejamento cuidadoso deve ser feito para garantir que os prompts tenham as regras necessárias e que a funcionalidade de pós-processamento seja incluída. Planeje mais tempo para implementar e testar esse tipo de funcionalidade e levar em conta cenários em que resultados inesperados são retornados.
- Com o OpenAI do Azure, os clientes obtêm os recursos de segurança do Microsoft Azure enquanto executam os mesmos modelos que o OpenAI. O OpenAI do Azure oferece rede privada, disponibilidade regional e filtragem de conteúdo de IA responsável. Saiba mais sobre Dados, privacidade e segurança para o Serviço OpenAI do Azure.
Agora você viu como usar o Azure OpenAI para converter linguagem natural em SQL e aprendeu sobre os prós e contras de implementar esse tipo de funcionalidade. No próximo exercício, você aprenderá como mensagens de email e SMS podem ser geradas usando o Azure OpenAI.
IA: Gerando conclusões
Além do recurso de linguagem natural para SQL, você também pode usar o Serviço OpenAI do Azure para gerar mensagens de email e SMS para aumentar a produtividade do usuário e simplificar os fluxos de trabalho de comunicação. Ao utilizar os recursos de geração de linguagem do Azure OpenAI, os usuários podem definir regras específicas, como "O pedido está atrasado em 5 dias" e o sistema gerará automaticamente mensagens de email e SMS contextualmente apropriadas com base nessas regras.
Esse recurso serve como um ponto de partida para os usuários, fornecendo a eles um modelo de mensagem cuidadosamente elaborado que eles podem personalizar facilmente antes de enviar. O resultado é uma redução significativa no tempo e esforço necessários para compor mensagens, permitindo que os usuários se concentrem em outras tarefas importantes. Além disso, a tecnologia de geração de linguagem do Azure OpenAI pode ser integrada aos fluxos de trabalho de automação, permitindo que o sistema gere e envie mensagens de forma autônoma em resposta a gatilhos predefinidos. Esse nível de automação não apenas acelera os processos de comunicação, mas também garante mensagens consistentes e precisas em vários cenários.
Neste exercício, você vai:
- Experimente diferentes prompts.
- Use prompts para gerar conclusões para mensagens de email e SMS.
- Explore o código que permite conclusões de IA.
- Saiba mais sobre a importância da engenharia rápida e da inclusão de regras em seus prompts.
Vamos começar experimentando diferentes regras que podem ser usadas para gerar mensagens de e-mail e SMS.
Usando o recurso de conclusão de IA
Em um exercício anterior, você iniciou o banco de dados, as APIs e o aplicativo. Você também atualizou o
.env
arquivo. Se você não concluiu essas etapas, siga as instruções no final do exercício antes de continuar.Volte para o navegador (http://localhost:4200) e selecione Entrar em contato com o cliente em qualquer linha na grade de dados seguido de E-mail/SMS do cliente para acessar a tela Gerador de mensagens.
Isso usa o OpenAI do Azure para converter regras de mensagem definidas em mensagens de email/SMS. Execute as seguintes tarefas:
Insira uma regra como Pedido atrasado 5 dias na entrada e selecione o botão Gerar mensagens de e-mail/SMS.
Você verá um assunto e um corpo gerados para o e-mail e uma mensagem curta gerada para o SMS.
Observação
Como os Serviços de Comunicação do Azure ainda não estão habilitados, você não poderá enviar o email ou mensagens SMS.
Feche a janela de diálogo de e-mail/SMS no navegador. Agora que você viu esse recurso em ação, vamos examinar como ele é implementado.
Explorando o código de conclusão de IA
Dica
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Abra o arquivo servidor/apiRoutes.ts e localize a
completeEmailSmsMessages
rota. Essa API é chamada pela parte front-end do aplicativo quando o botão Gerar mensagens de email/SMS é selecionado. Ele recupera os valores de prompt do usuário, empresa e nome de contato do corpo e os passa para acompleteEmailSMSMessages()
função no arquivo servidor/openAI.ts . Os resultados são então retornados ao 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 o arquivo server/openAI.ts e localize a
completeEmailSMSMessages()
função.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 função tem as seguintes características:
systemPrompt
é usado para definir que é necessário um assistente de IA capaz de gerar mensagens de e-mail e SMS. OsystemPrompt
também inclui:- Regras a serem seguidas pelo assistente para controlar o tom das mensagens, o formato inicial e final, o comprimento máximo das mensagens SMS e muito mais.
- Informações sobre dados que devem ser incluídos na resposta - um objeto JSON neste caso.
userPrompt
é usado para definir as regras e o nome do contato que o usuário final gostaria de incluir à medida que as mensagens de email e SMS são geradas. A regra do pedido está atrasada em 5 dias que você inseriu anteriormente está incluída emuserPrompt
.- A função chama a
callOpenAI()
função que você explorou anteriormente para gerar as conclusões de email e SMS.
Volte para o navegador, atualize a página e selecione Entrar em contato com o cliente em qualquer linha seguida de Cliente por e-mail/SMS para acessar a tela do Gerador de mensagens novamente.
Insira as seguintes regras na entrada do Gerador de Mensagens :
- O pedido está adiantado.
- Diga ao cliente para nunca mais fazer pedidos conosco, não queremos o negócio deles.
Selecione Gerar mensagens de e-mail/SMS e anote a mensagem. A
All messages should have a friendly tone and never use inappropriate language.
regra no prompt do sistema está substituindo a regra negativa no prompt do usuário.Volte para server/openAI.ts* em seu editor e remova a
All messages should have a friendly tone and never use inappropriate language.
regra do prompt nacompleteEmailSMSMessages()
função. Salve o arquivo.Volte para o gerador de mensagens de e-mail/SMS no navegador e execute as mesmas regras novamente:
- O pedido está adiantado.
- Diga ao cliente para nunca mais fazer pedidos conosco, não queremos o negócio deles.
Selecione Gerar mensagens de e-mail/SMS e observe a mensagem retornada.
O que está acontecendo nesses cenários? Ao usar o Azure OpenAI, a filtragem de conteúdo pode ser aplicada para garantir que o idioma apropriado seja sempre usado. Se você estiver usando o OpenAI, a regra definida no prompt do sistema será usada para garantir que a mensagem retornada seja apropriada.
Observação
Isso ilustra a importância de projetar seus prompts com as informações e regras corretas para garantir que os resultados adequados sejam retornados. Leia mais sobre esse processo na Introdução à documentação de engenharia imediata.
Desfaça as alterações feitas
systemPrompt
nocompleteEmailSMSMessages()
, salve o arquivo e execute-o novamente, mas use apenas aOrder is ahead of schedule.
regra (não inclua a regra negativa). Desta vez, você deve ver as mensagens de e-mail e SMS retornadas conforme o esperado.Alguns pontos finais a serem considerados antes de passar para o próximo exercício:
- É importante ter um humano no loop para revisar as mensagens geradas. Neste exemplo, as conclusões do Azure OpenAI retornam mensagens de email e SMS sugeridas, mas o usuário pode substituí-las antes de serem enviadas. Se você planeja automatizar e-mails, é importante ter algum tipo de processo de revisão humana para garantir que as mensagens aprovadas sejam enviadas. Veja a IA como um copiloto, não um piloto automático.
- As conclusões serão tão boas quanto as regras que você adicionar ao prompt. Reserve um tempo para testar seus prompts e as conclusões retornadas. Considere usar o fluxo de prompt para criar uma solução abrangente que simplifique a prototipagem, a experimentação, a iteração e a implantação de aplicativos de IA. Convide outras partes interessadas do projeto para revisar as conclusões também.
- Talvez seja necessário incluir código de pós-processamento para garantir que resultados inesperados sejam tratados corretamente.
- Use prompts do sistema para definir as regras e informações que o assistente de IA deve seguir. Use prompts do usuário para definir as regras e informações que o usuário final gostaria de incluir nas conclusões.
IA: Azure OpenAI em seus dados
A integração do NLP (Processamento de Linguagem Natural) do OpenAI do Azure e dos recursos de conclusão oferece um potencial significativo para aumentar a produtividade do usuário. Ao aproveitar prompts e regras apropriados, um assistente de IA pode gerar com eficiência várias formas de comunicação, como mensagens de e-mail, mensagens SMS e muito mais. Essa funcionalidade leva a uma maior eficiência do usuário e fluxos de trabalho simplificados.
Embora esse recurso seja bastante poderoso por si só, pode haver casos em que os usuários precisem gerar conclusões com base nos dados personalizados da sua empresa. Por exemplo, você pode ter uma coleção de manuais de produtos que podem ser difíceis para os usuários navegarem quando estiverem ajudando os clientes com problemas de instalação. Como alternativa, você pode manter um conjunto abrangente de perguntas frequentes (FAQs) relacionadas aos benefícios de saúde que podem ser difíceis para os usuários lerem e obterem as respostas de que precisam. Nesses casos e em muitos outros, o Serviço OpenAI do Azure permite que você aproveite seus próprios dados para gerar conclusões, garantindo uma resposta mais personalizada e contextualmente precisa às perguntas do usuário.
Aqui está uma visão geral rápida de como o recurso "traga seus próprios dados" funciona na documentação do OpenAI do Azure.
Observação
Um dos principais recursos do OpenAI do Azure com seus dados é a capacidade de recuperar e utilizar os dados para melhorar a saída do modelo. A OpenAI do Azure com seus dados, junto com a Pesquisa de IA do Azure, determina quais dados serão recuperados da fonte de dados designada com base na entrada do usuário e no histórico de conversas fornecido. Esses dados então são aumentados e reenviados como um prompt para o modelo do OpenAI, com informações recuperadas sendo acrescentadas ao prompt original. Embora os dados recuperados estejam sendo acrescentados ao prompt, a entrada resultante ainda é processada pelo modelo como qualquer outro prompt. Depois que os dados forem recuperados e o prompt tiver sido enviado ao modelo, o modelo usará essas informações para fornecer uma conclusão.
Neste exercício, você vai:
- Crie uma fonte de dados personalizada usando o Azure AI Studio.
- Implante um modelo de inserção usando o Azure AI Studio.
- Carregue documentos personalizados.
- Inicie uma sessão de chat no playground do Chat para experimentar a geração de conclusões com base em seus próprios dados.
- Explore o código que usa o Azure AI Search e o Azure OpenAI para gerar conclusões com base em seus próprios dados.
Vamos começar implantando um modelo de inserção e adicionando uma fonte de dados personalizada no Azure AI Studio.
Adicionando uma fonte de dados personalizada ao Azure AI Studio
Navegue até o Azure OpenAI Studio e entre com credenciais que tenham acesso ao recurso do OpenAI do Azure.
Selecione Implantações no menu de navegação.
Selecione Selecionar Implantar modelo --Implantar modelo base na barra de> ferramentas.
Selecione o modelo text-embedding-ada-002 na lista de modelos e selecione Confirmar.
Selecione as seguintes opções:
- Nome da implantação: text-embedding-ada-002
- Versão do modelo: Padrão
- Tipo de implantação: Padrão
- Defina o valor do Limite de Taxa de Tokens por Minuto (milhares) para 120K
- Filtro de conteúdo: DefaultV2
- Ativar cotação dinâmica: Ativado
Selecione o botão Implantar.
Depois que o modelo for criado, selecione Início no menu de navegação para ir para a tela de boas-vindas.
Localize o bloco Traga seus próprios dados na tela de boas-vindas e selecione Experimente agora.
Selecione Adicionar seus dados seguido de Adicionar uma fonte de dados.
No menu suspenso Selecionar fonte de dados, selecione Carregar arquivos.
Na lista suspensa Selecionar recurso de armazenamento de Blobs do Azure, selecione Criar um novo recurso de armazenamento de Blobs do Azure.
Selecione sua assinatura do Azure na lista suspensa Assinatura .
Na lista suspensa Selecionar recurso de armazenamento de Blobs do Azure, selecione Criar um novo recurso de armazenamento de Blobs do Azure.
Isso o levará ao portal do Azure, onde você pode executar as seguintes tarefas:
- Insira um nome exclusivo para a conta de armazenamento, como byodstorage[Seu sobrenome].
- Selecione uma região próxima à sua localização.
- Selecione Revisar seguido de Criar.
Depois que o recurso de armazenamento de blobs for criado, volte para a caixa de diálogo do Azure AI Studio e selecione o recurso de armazenamento de blobs recém-criado na lista suspensa Selecionar recurso de armazenamento de Blobs do Azure. Se você não o vir listado, selecione o ícone de atualização ao lado da lista suspensa.
O CORS (compartilhamento de recursos entre origens) precisa ser ativado para que sua conta de armazenamento seja acessada. Selecione Ativar CORS na caixa de diálogo Azure AI Studio.
Na lista suspensa Selecionar recurso do Azure AI Search, selecione Criar um novo recurso do Azure AI Search.
Isso o levará de volta ao portal do Azure, onde você pode executar as seguintes tarefas:
- Insira um nome exclusivo para o recurso do AI Search, como byodsearch-[Your Last Name].
- Selecione uma região próxima à sua localização.
- Na seção Tipo de preço, selecione Alterar Tipo de Preço e selecione Básico seguido de Selecionar. Não há suporte para o nível gratuito, portanto, você limpará o recurso do AI Search no final deste tutorial.
- Selecione Revisar seguido de Criar.
Depois que o recurso do AI Search for criado, vá para a página Visão geral do recurso e copie o valor do URL para um arquivo local.
Selecione Configurações -->Teclas no menu de navegação.
Na página Controle de acesso à API, selecione Ambos para permitir que o serviço seja acessado usando a Identidade Gerenciada ou usando uma chave. Selecione Sim quando solicitado.
Observação
Embora usemos uma chave de API neste exercício, já que a adição de atribuições de função pode levar até 10 minutos, com um pouco de esforço adicional, você pode habilitar uma identidade gerenciada atribuída pelo sistema para acessar o serviço com mais segurança.
Selecione Chaves no menu de navegação à esquerda e copie o valor da chave de administração primária para um arquivo local. Você precisará do URL e dos valores-chave mais adiante no exercício.
Selecione Configurações -->Semantic ranker no menu de navegação e verifique se Livre está selecionado.
Observação
Para verificar se o classificador semântico está disponível em uma região específica, verifique a página Produtos disponíveis por região no site do Azure para ver se sua região está listada.
Volte para a caixa de diálogo Adicionar Dados do Azure AI Studio e selecione o recurso de pesquisa recém-criado na lista suspensa Selecionar recurso do Azure AI Search. Se você não o vir listado, selecione o ícone de atualização ao lado da lista suspensa.
Insira um valor de byod-search-index para o valor Insira o nome do índice.
Marque a caixa de seleção Adicionar pesquisa vetorial a este recurso de pesquisa.
No menu suspenso Selecionar um modelo de incorporação, selecione o modelo text-embedding-ada-002 que você criou anteriormente.
Na caixa de diálogo Carregar arquivos, selecione Procurar um arquivo.
Navegue até a pasta de documentos do cliente do projeto (localizada na raiz do projeto) e selecione os seguintes arquivos:
- Relógio A102 Instructions.docx de instalação
- Empresa FAQs.docx
Observação
Atualmente, esse recurso oferece suporte aos seguintes formatos de arquivo para criação de índice local: .txt, .md, .html, .pdf, .docx e .pptx.
Selecione Carregar arquivos. Os arquivos serão carregados em um contêiner fileupload-byod-search-index no recurso de armazenamento de blobs que você criou anteriormente.
Selecione Avançar para ir para a caixa de diálogo Gerenciamento de dados.
Na lista suspensa Tipo de pesquisa, selecione Híbrido + semântico.
Observação
Essa opção fornece suporte para pesquisa de palavras-chave e vetores. Depois que os resultados são retornados, um processo de classificação secundário é aplicado ao conjunto de resultados usando modelos de aprendizado profundo, o que melhora a relevância da pesquisa para o usuário. Para saber mais sobre a pesquisa semântica, consulte a documentação Pesquisa semântica no Azure AI Search .
Certifique-se de que o valor Selecionar um tamanho esteja definido como 1024.
Selecione Avançar.
Para o tipo de autenticação de recurso do Azure, selecione Chave de API. Saiba mais sobre como selecionar o tipo de autenticação correto na documentação de autenticação do Azure AI Search.
Selecione Avançar.
Examine os detalhes e selecione Salvar e fechar.
Agora que seus dados personalizados foram carregados, eles serão indexados e estarão disponíveis para uso no playground do Chat. Esse processo pode levar alguns minutos. Depois de concluído, continue para a próxima seção.
Como usar sua fonte de dados personalizada no playground do Chat
Localize a seção Sessão de chat da página no Azure OpenAI Studio e insira a seguinte consulta de usuário:
What safety rules are required to install a clock?
Depois de enviar a consulta do usuário, você deverá ver um resultado semelhante ao seguinte: exibido:
Expanda a seção 1 referências na resposta do chat e observe que o arquivo Instructions.docx de instalação do Clock A102 está listado e que você pode selecioná-lo para visualizar o documento.
Digite a seguinte mensagem de usuário:
What should I do to mount the clock on the wall?
Você deve ver um resultado semelhante ao seguinte exibido:
Agora vamos experimentar o documento de perguntas frequentes da empresa. Insira o seguinte texto no campo Consulta do usuário:
What is the company's policy on vacation time?
Você deve ver que nenhuma informação foi encontrada para essa solicitação.
Insira o seguinte texto no campo Consulta do usuário:
How should I handle refund requests?
Você deve ver um resultado semelhante ao seguinte exibido:
Expanda a seção 1 referências na resposta do chat e observe que o arquivo FAQs.docx da empresa está listado e que você pode selecioná-lo para visualizar o documento.
Selecione Exibir código na barra de ferramentas do playground do Chat.
Observe que você pode alternar entre diferentes idiomas, visualizar o endpoint e acessar a chave do endpoint. Feche a janela de diálogo Código de Exemplo.
Ative a opção Mostrar JSON bruto acima das mensagens de bate-papo. Observe que a sessão de chat começa com uma mensagem semelhante à seguinte:
{ "role": "system", "content": "You are an AI assistant that helps people find information." }
Agora que você criou uma fonte de dados personalizada e a experimentou no playground do Chat, vamos ver como você pode usá-la no aplicativo do projeto.
Usando o recurso Traga seus próprios dados no aplicativo
Volte para o projeto no VS Code e abra o arquivo .env . Atualize os valores a seguir com o ponto de extremidade, a chave e o nome do índice do AI Services. Você copiou o ponto de extremidade e a chave para um arquivo local anteriormente neste exercício.
AZURE_AI_SEARCH_ENDPOINT=<AI_SERVICES_ENDPOINT_VALUE> AZURE_AI_SEARCH_KEY=<AI_SERVICES_KEY_VALUE> AZURE_AI_SEARCH_INDEX=byod-search-index
Em um exercício anterior, você iniciou o banco de dados, as APIs e o aplicativo. Você também atualizou o
.env
arquivo. Se você não concluiu essas etapas, siga as instruções no final do exercício anterior antes de continuar.Depois que o aplicativo for carregado no navegador, selecione o ícone Ajuda do Chat no canto superior direito do aplicativo.
O seguinte texto deve aparecer na caixa de diálogo de bate-papo:
How should I handle a company refund request?
Selecione o botão Obter ajuda . Você deve ver os resultados retornados do documento FAQs.docx Empresa que você carregou anteriormente no Azure OpenAI Studio. Se você quiser ler o documento, poderá encontrá-lo na pasta de documentos do cliente na raiz do projeto.
Altere o texto para o seguinte e selecione o botão Obter ajuda :
What safety rules are required to install a clock?
Você deve ver os resultados retornados do documento Instructions.docx de instalação do Relógio A102 que você carregou anteriormente no Azure OpenAI Studio. Este documento também está disponível na pasta de documentos do cliente na raiz do projeto.
Explorando o código
Dica
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Volte para o código-fonte do projeto no Visual Studio Code.
Abra o arquivo servidor/apiRoutes.ts e localize a
completeBYOD
rota. Essa API é chamada quando o botão Obter ajuda é selecionado na caixa de diálogo Ajuda do Chat. Ele recupera o prompt do usuário do corpo da solicitação e o passa para acompleteBYOD()
função no arquivo server/openAI.ts . Os resultados são então retornados ao 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 o arquivo server/openAI.ts e localize a
completeBYOD()
função.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 função tem as seguintes características:
- O
userPrompt
parâmetro contém as informações que o usuário digitou na caixa de diálogo de ajuda do chat. - a
systemPrompt
variável define que será usado um assistente de IA projetado para ajudar as pessoas a encontrar informações. callOpenAI()
é usado para chamar a API do OpenAI do Azure e retornar os resultados. Ele passa ossystemPrompt
valores euserPrompt
bem como os seguintes parâmetros:temperature
- A quantidade de criatividade a ser incluída na resposta. O usuário precisa de respostas consistentes (menos criativas) nesse caso, portanto, o valor é definido como 0.useBYOD
- Um valor booliano que indica se deve ou não usar o AI Search junto com o Azure OpenAI. Nesse caso, ele está definido para que atrue
funcionalidade de Pesquisa de IA seja usada.
- O
A
callOpenAI()
função aceita umuseBYOD
parâmetro que é usado para determinar qual função OpenAI chamar. Nesse caso, ele é definidouseBYOD
comotrue
para que agetAzureOpenAIBYODCompletion()
função seja chamada.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); }
Localize a
getAzureOpenAIBYODCompletion()
função em server/openAI.ts. É bastante semelhante à função que você examinou anteriormente, mas é mostradagetAzureOpenAICompletion()
como uma função separada para destacar algumas diferenças importantes que são exclusivas do cenário "Azure OpenAI em seus dados" disponível no 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 a seguinte funcionalidade na
getAzureOpenAIBYODCompletion()
função:- É criada uma
dataSources
propriedade que contém os valores ,endpoint
eindex_name
e do recursokey
do AI Search que foram adicionados ao.env
arquivo anteriormente neste exercício - A
createAzureOpenAICompletion()
função é chamada com ossystemPrompt
valores ,userPrompt
,temperature
, edataSources
. Essa função é usada para chamar a API do OpenAI do Azure e retornar os resultados. - Depois que a resposta é retornada, as citações do documento são registradas no console. O conteúdo da mensagem de conclusão é então retornado ao chamador.
- É criada uma
Alguns pontos finais a serem considerados antes de passar para o próximo exercício:
- O aplicativo de exemplo usa um único índice no Azure AI Search. Você pode usar vários índices e fontes de dados com o Azure OpenAI. A
dataSources
propriedade na função pode ser atualizada para incluir várias fontes de dados,getAzureOpenAIBYODCompletion()
conforme necessário. - A segurança deve ser cuidadosamente avaliada com esse tipo de cenário. Os usuários não devem ser capazes de fazer perguntas e obter resultados de documentos que não podem acessar.
- O aplicativo de exemplo usa um único índice no Azure AI Search. Você pode usar vários índices e fontes de dados com o Azure OpenAI. A
Agora que você aprendeu sobre o Azure OpenAI, prompts, conclusões e como usar seus próprios dados, vamos para o próximo exercício para saber como os recursos de comunicação podem ser usados para aprimorar o aplicativo. Se você quiser saber mais sobre o Azure OpenAI, confira o conteúdo de treinamento Introdução ao Serviço OpenAI do Azure. Informações adicionais sobre como usar seus próprios dados com o Azure OpenAI podem ser encontradas na documentação do Azure OpenAI em seus dados .
Comunicação: Criando um recurso dos Serviços de Comunicação do Azure
A comunicação eficaz é essencial para aplicativos de negócios personalizados bem-sucedidos. Usando os Serviços de Comunicação do Azure (ACS), você pode adicionar recursos como chamadas telefônicas, chat ao vivo, chamadas de áudio/vídeo e mensagens de email e SMS aos seus aplicativos. Anteriormente, você aprendeu como o Azure OpenAI pode gerar conclusões para mensagens de email e SMS. Agora, você aprenderá como enviar as mensagens. Juntos, o ACS e o OpenAI podem aprimorar seus aplicativos simplificando a comunicação, melhorando as interações e aumentando a produtividade dos negócios.
Neste exercício, você vai:
- Crie um recurso do ACS (Serviços de Comunicação do Azure).
- Adicione um número de telefone gratuito com recursos de chamadas e SMS.
- Conecte um domínio de e-mail.
- Atualize o arquivo .env do projeto com valores do recurso ACS.
Criar um recurso dos Serviços de Comunicação do Azure
Visite o portal do Azure em seu navegador e entre, caso ainda não tenha feito isso.
Digite serviços de comunicação na barra de pesquisa na parte superior da página e selecione Serviços de Comunicação nas opções exibidas.
Selecione Criar na barra de ferramentas.
Execute as seguintes tarefas:
- Selecione sua assinatura do Azure.
- Selecione o grupo de recursos a ser usado (crie um novo se não houver um).
- Insira um nome de recurso do ACS. Ele precisa ser um valor exclusivo.
- Selecione um local de dados.
Selecione Examinar + Criar seguido de Criar.
Você criou com êxito um novo recurso dos Serviços de Comunicação do Azure! Em seguida, você ativará os recursos de chamadas telefônicas e SMS. Você também conectará um domínio de e-mail ao recurso.
Ativar recursos de chamadas telefônicas e SMS
Adicione um número de telefone e verifique se o número de telefone tem recursos de chamada habilitados. Você usará esse número de telefone para ligar para um telefone a partir do aplicativo.
Selecione Telefonia e SMS -->Números de telefone no menu Recursos.
Selecione + Obter na barra de ferramentas (ou selecione o botão Obter um número ) e insira as seguintes informações:
- País ou região:
United States
- Tipo de número:
Toll-free
Observação
É necessário um cartão de crédito em sua assinatura do Azure para criar o número gratuito. Se você não tiver um cartão registrado, fique à vontade para pular a adição de um número de telefone e pular para a próxima seção do exercício que conecta um domínio de e-mail. Você ainda pode usar o aplicativo, mas não poderá ligar para um número de telefone.
- Número: Selecione Adicionar ao carrinho para um dos números de telefone listados.
- País ou região:
Selecione Avançar, examine os detalhes do número de telefone e selecione Comprar agora.
Observação
A verificação por SMS para números gratuitos agora é obrigatória nos Estados Unidos e no Canadá. Para ativar as mensagens SMS, você deve enviar a verificação após a compra do número de telefone. Embora este tutorial não passe por esse processo, você pode selecionar Telefonia e SMS -->Documentos Regulatórios no menu de recursos e adicionar a documentação de validação necessária.
Depois que o número de telefone for criado, selecione-o para acessar o painel Recursos . Certifique-se de que os seguintes valores estejam definidos (eles devem ser definidos por padrão):
- Na seção Chamada, selecione
Make calls
. - Na seção SMS, selecione
Send and receive SMS
. - Selecione Salvar.
- Na seção Chamada, selecione
Copie o valor do número de telefone em um arquivo para uso posterior. O número de telefone deve seguir este padrão geral:
+12345678900
.
Conectar um domínio de e-mail
Execute as tarefas a seguir para criar um domínio de email conectado para o recurso do ACS para que você possa enviar emails. Isso será usado para enviar e-mails do aplicativo.
- Selecione E-mail -->Domains no menu Recurso.
- Selecione Conectar domínio na barra de ferramentas.
- Selecione sua Assinatura e Grupo de recursos.
- No menu suspenso Serviço de e-mail, selecione
Add an email service
. - Dê ao serviço de e-mail um nome como
acs-demo-email-service
. - Selecione Examinar + criar seguido de Criar.
- Depois que a implantação for concluída, selecione
Go to resource
e selecione1-click add
para adicionar um subdomínio gratuito do Azure. - Depois que o subdomínio for adicionado (levará alguns instantes para ser implantado), selecione-o.
- Quando estiver na tela AzureManagedDomain, selecione Serviços de email -->MailFrom addresses no menu Recurso.
- Copie o valor MailFrom para um arquivo. Você o usará mais tarde ao atualizar o arquivo .env .
- Volte para o recurso dos Serviços de Comunicação do Azure e selecione Email -->Domains no menu de recursos.
- Selecione
Add domain
e insira oMailFrom
valor da etapa anterior (certifique-se de selecionar a assinatura, o grupo de recursos e o serviço de email corretos). Selecione o botãoConnect
.
Atualize o .env
arquivo
Agora que o número de telefone do ACS (com chamadas e SMS habilitados) e o domínio de email estão prontos, atualize as seguintes chaves/valores no arquivo .env em seu projeto:
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
: oconnection string
valor da seção Chaves do recurso ACS.ACS_PHONE_NUMBER
: atribua seu número de chamada gratuita aoACS_PHONE_NUMBER
valor.ACS_EMAIL_ADDRESS
: Atribua o valor do endereço de e-mail "MailTo".CUSTOMER_EMAIL_ADDRESS
: atribua um endereço de e-mail para o qual você deseja que o e-mail seja enviado do aplicativo (já que os dados do cliente no banco de dados do aplicativo são apenas dados de amostra). Você pode usar um endereço de e-mail pessoal.CUSTOMER_PHONE_NUMBER
: Você precisará fornecer um número de telefone nos Estados Unidos (a partir de hoje) devido à verificação adicional exigida em outros países para enviar mensagens SMS. Se você não tiver um número nos EUA, poderá deixá-lo vazio.
Iniciar/reiniciar os servidores de aplicativos e API
Execute uma das seguintes etapas com base nos exercícios concluídos até este ponto:
Se você iniciou o banco de dados, o servidor de API e o servidor Web em um exercício anterior, será necessário interromper o servidor de API e o servidor Web e reiniciá-los para selecionar as alterações do arquivo .env . Você pode deixar o banco de dados em execução.
Localize as janelas do terminal que executam o servidor de API e o servidor web e pressione CTRL + C para pará-las. Inicie-os novamente digitando
npm start
em cada janela do terminal e pressionando Enter. Continue para o próximo exercício.Se você ainda não iniciou o banco de dados, o servidor de API e o servidor Web, conclua as seguintes etapas:
Nas etapas a seguir, você criará três janelas de terminal no Visual Studio Code.
Clique com o botão direito do mouse no arquivo .env na lista de arquivos do Visual Studio Code e selecione Abrir no Terminal Integrado. Certifique-se de que seu terminal esteja na raiz do projeto - openai-acs-msgraph - antes de continuar.
Escolha uma das seguintes opções para iniciar o banco de dados PostgreSQL:
Se você tiver o Docker Desktop instalado e em execução, execute
docker-compose up
na janela do terminal e pressione Enter.Se você tiver o Podman com o podman-compose instalado e em execução, execute
podman-compose up
na janela do terminal e pressione Enter.Para executar o contêiner do PostgreSQL diretamente usando o Docker Desktop, o Podman, o nerdctl ou outro tempo de execução do contêiner que você instalou, execute o seguinte comando na janela do terminal:
Subsistema Mac, Linux ou 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 com 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
Depois que o contêiner do banco de dados for iniciado, pressione o + ícone na barra de ferramentas do Terminal do Visual Studio Code para criar uma segunda janela de terminal.
cd
na pasta server/typescript e execute os comandos a seguir para instalar as dependências e iniciar o servidor de API.npm install
npm start
Pressione o + ícone novamente na barra de ferramentas do Terminal do Visual Studio Code para criar uma terceira janela de terminal.
cd
na pasta do cliente e execute os comandos a seguir para instalar as dependências e iniciar o servidor Web.npm install
npm start
Um navegador será iniciado e você será direcionado para http://localhost:4200.
Comunicação: Fazendo uma chamada telefônica
A integração dos recursos de chamada telefônica dos Serviços de Comunicação do Azure em um aplicativo LOB (Linha de Negócios) personalizado oferece vários benefícios importantes para as empresas e seus usuários:
- Permite a comunicação contínua e em tempo real entre funcionários, clientes e parceiros, diretamente de dentro do aplicativo LOB, eliminando a necessidade de alternar entre várias plataformas ou dispositivos.
- Aprimora a experiência do usuário e melhora a eficiência operacional geral.
- Facilita a resolução rápida de problemas, pois os usuários podem se conectar rapidamente com equipes de suporte relevantes ou especialistas no assunto de forma rápida e fácil.
Neste exercício, você vai:
- Explore o recurso de chamada telefônica no aplicativo.
- Percorra o código para saber como o recurso de chamada telefônica é criado.
Usando o recurso de chamada telefônica
No exercício anterior, você criou um recurso do ACS (Serviços de Comunicação do Azure) e iniciou o banco de dados, o servidor Web e o servidor de API. Você também atualizou os seguintes valores no arquivo .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>
Certifique-se de ter concluído o exercício anterior antes de continuar.
Volte para o navegador (http://localhost:4200), localize a grade de dados e selecione Entrar em contato com o cliente seguido de Ligar para o cliente na primeira linha.
Um componente de chamada telefônica será adicionado ao cabeçalho. Insira o número de telefone para o qual deseja ligar (certifique-se de que comece com + e inclua o código do país) e selecione Ligar. Você será solicitado a permitir o acesso ao seu microfone.
Selecione Desligar para encerrar a chamada. Selecione Fechar para fechar o componente de chamada telefônica.
Explorando o código de chamada telefônica
Dica
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Abra o arquivo customers-list.component.ts . O caminho completo para o arquivo é client/src/app/customers-list/customers-list.component.ts.
Observe que
openCallDialog()
envia umaCustomerCall
mensagem e o número de telefone do cliente usando um barramento de eventos.openCallDialog(data: Phone) { this.eventBus.emit({ name: Events.CustomerCall, value: data }); }
Observação
O código do barramento de eventos pode ser encontrado no arquivo eventbus.service.ts se você estiver interessado em explorá-lo mais. O caminho completo para o arquivo é client/src/app/core/eventbus.service.ts.
A função do
ngOnInit()
componente de cabeçalho assina oCustomerCall
evento enviado pelo barramento de eventos e exibe o componente de chamada telefônica. Você pode encontrar esse código em 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. Reserve um momento para expor o código. O caminho completo para o arquivo é client/src/app/phone-call/phone-call.component.ts. Observe os seguintes recursos principais:
- Recupera um token de acesso dos Serviços de Comunicação do Azure chamando a
acsService.getAcsToken()
função emngOnInit()
; - Adiciona um "discador de telefone" à página. Você pode ver o discador clicando na entrada do número de telefone no cabeçalho.
- Inicia e encerra uma chamada usando as
startCall()
funções eendCall()
respectivamente.
- Recupera um token de acesso dos Serviços de Comunicação do Azure chamando a
Antes de examinar o código que faz a chamada telefônica, vamos examinar como o token de acesso do ACS é recuperado e como os objetos de chamada telefônica são criados. Localize a
ngOnInit()
função em 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); }) ); } }
Essa função executa as seguintes ações:
- Recupera um userId do ACS e um token de acesso chamando a
acsService.getAcsToken()
função. - Depois que o token de acesso é recuperado, o código executa as seguintes ações:
- Cria uma nova instância e
AzureCommunicationTokenCredential
usa o token deCallClient
acesso. - Cria uma nova instância do uso dos
CallAgent
CallClient
objetos andAzureCommunicationTokenCredential
. Mais tarde, você verá queCallAgent
é usado para iniciar e encerrar uma chamada.
- Cria uma nova instância e
- Recupera um userId do ACS e um token de acesso chamando a
Abra acs.services.ts e localize a
getAcsToken()
função. O caminho completo para o arquivo é client/src/app/core/acs.service.ts. A função faz uma solicitação HTTP GET para a/acstoken
rota exposta pelo servidor de API.getAcsToken(): Observable<AcsUser> { return this.http.get<AcsUser>(this.apiUrl + 'acstoken') .pipe( catchError(this.handleError) ); }
Uma função de servidor de API chamada
createACSToken()
recupera o userId e o token de acesso e os retorna ao cliente. Ele pode ser encontrado no arquivo 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 }; }
Essa função executa as seguintes ações:
- Verifica se um valor ACS
connectionString
está disponível. Caso contrário, retorna um objeto com um arquivo vaziouserId
etoken
. - Cria uma nova instância e
CommunicationIdentityClient
passa oconnectionString
valor para ela. - Cria um novo usuário e token usando
tokenClient.createUserAndToken()
o escopo "voip". - Retorna um objeto que contém os
userId
valores etoken
.
- Verifica se um valor ACS
Agora que você viu como o userId e o token são recuperados, volte e
phone-call.component.ts
localize astartCall()
função.Essa função é chamada quando Chamada é selecionada no componente de chamada telefônica. Ele usa o
CallAgent
objeto mencionado anteriormente para iniciar uma chamada. AcallAgent.startCall()
função aceita um objeto que representa o número a ser chamado e o número de telefone do ACS usado para fazer a chamada.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; } }); }
A
endCall()
função é chamada quando Desligar é selecionado no componente de chamada telefônica.endCall() { if (this.call) { this.call.hangUp({ forEveryone: true }); this.call = undefined; this.inCall = false; } else { this.hangup.emit(); } }
Se uma chamada estiver em andamento, a
call.hangUp()
função será chamada para encerrar a chamada. Se nenhuma chamada estiver em andamento, ohangup
evento será emitido para o componente pai do cabeçalho para ocultar o componente de chamada telefônica.Antes de passar para o próximo exercício, vamos examinar os principais conceitos abordados neste exercício:
- Um userId e um token de acesso do ACS são recuperados do servidor de API usando a
acsService.createUserAndToken()
função. - O token é usado para criar um
CallClient
objeto andCallAgent
. - O
CallAgent
objeto é usado para iniciar e encerrar uma chamada chamando ascallAgent.startCall()
funções ecallAgent.hangUp()
respectivamente.
- Um userId e um token de acesso do ACS são recuperados do servidor de API usando a
Agora que você aprendeu como as chamadas telefônicas podem ser integradas a um aplicativo, vamos mudar nosso foco para usar os Serviços de Comunicação do Azure para enviar mensagens de email e SMS.
Comunicação: Envio de mensagens de e-mail e SMS
Além de chamadas telefônicas, os Serviços de Comunicação do Azure também podem enviar mensagens de email e SMS. Isso pode ser útil quando você deseja enviar uma mensagem para um cliente ou outro usuário diretamente do aplicativo.
Neste exercício, você vai:
- Explore como as mensagens de e-mail e SMS podem ser enviadas a partir do aplicativo.
- Percorra o código para saber como a funcionalidade de email e SMS é implementada.
Usando os recursos de e-mail e SMS
Em um exercício anterior, você criou um recurso do ACS (Serviços de Comunicação do Azure) e iniciou o banco de dados, o servidor Web e o servidor de API. Você também atualizou os seguintes valores no arquivo .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>
Certifique-se de ter concluído o exercício antes de continuar.
Volte para o navegador (http://localhost:4200) e selecione Entrar em contato com o cliente seguido de E-mail/SMS do cliente na primeira linha.
Selecione a guia E-mail/SMS e execute as seguintes tarefas:
- Insira um assunto e um corpo do e-mail e selecione o botão Enviar e-mail.
- Insira uma mensagem SMS e selecione o botão Enviar SMS .
Observação
A verificação por SMS para números gratuitos agora é obrigatória nos Estados Unidos e no Canadá. Para ativar as mensagens SMS, você deve enviar a verificação após a compra do número de telefone. Embora este tutorial não passe por esse processo, você pode selecionar Telefonia e SMS -->Documentos Regulatórios no recurso Serviços de Comunicação do Azure no portal do Azure e adicionar a documentação de validação necessária.
Verifique se você recebeu o e-mail e as mensagens SMS. A funcionalidade SMS só funcionará se você tiver enviado os documentos regulamentares mencionados na nota anterior. Como lembrete, a mensagem de email será enviada para o valor definido para
CUSTOMER_EMAIL_ADDRESS
e a mensagem SMS será enviada para o valor definido paraCUSTOMER_PHONE_NUMBER
no arquivo .env . Se você não conseguiu fornecer um número de telefone baseado nos Estados Unidos para usar em mensagens SMS, pode pular essa etapa.Observação
Se você não vir a mensagem de email em sua caixa de entrada para o endereço definido
CUSTOMER_EMAIL_ADDRESS
no arquivo .env , verifique sua pasta de spam.
Explorando o código de e-mail
Dica
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Abra o arquivo customers-list.component.ts . O caminho completo para o arquivo é client/src/app/customers-list/customers-list.component.ts.
Quando você selecionou Entrar em contato com o cliente seguido de Cliente por email/SMS na grade de dados, o
customer-list
componente exibiu uma caixa de diálogo. Isso é tratado pelaopenEmailSmsDialog()
função no arquivo 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.'); } }
A
openEmailSmsDialog()
função executa as seguintes tarefas:- Verifica se o
data
objeto (que representa a linha da grade de dados) contém umaphone
propriedade andemail
. Em caso afirmativo, ele cria umdialogData
objeto que contém as informações a serem passadas para a caixa de diálogo. - Abre a
EmailSmsDialogComponent
caixa de diálogo e passa odialogData
objeto para ela. - Assina o
afterClosed()
evento da caixa de diálogo. Esse evento é acionado quando a caixa de diálogo é fechada. Oresponse
objeto contém as informações que foram inseridas na caixa de diálogo.
- Verifica se o
Abra o arquivo email-sms-dialog.component.ts . O caminho completo para o arquivo é client/src/app/email-sms-dialog/email-sms-dialog.component.ts.
Localize a
sendEmail()
função: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 } }
A
sendEmail()
função executa as seguintes tarefas:- Verifica se o sinalizador de
acsEmailEnabled
recurso está definido comotrue
. Esse sinalizador verifica se aACS_EMAIL_ADDRESS
variável de ambiente tem um valor atribuído. - Se
acsEmailEnabled
for true, a função será chamada e o assunto, oacsService.sendEmail()
corpo, o nome do cliente e o endereço de email do cliente serão passados. Como o banco de dados contém dados de amostra, aCUSTOMER_EMAIL_ADDRESS
variável de ambiente é usada em vez dethis.data.email
. Em um aplicativo do mundo real, othis.data.email
valor seria usado. - Subscreve a
sendEmail()
função noacsService
serviço. Essa função retorna um RxJS observável que contém a resposta do serviço do lado do cliente. - Se o e-mail foi enviado com êxito, a
emailSent
propriedade é definida comotrue
.
- Verifica se o sinalizador de
Para fornecer melhor encapsulamento e reutilização de código, serviços do lado do cliente, como acs.service.ts são usados em todo o aplicativo. Isso permite que todas as funcionalidades do ACS sejam consolidadas em um único local.
Abra acs.service.ts e localize a
sendEmail()
função. O caminho completo para o arquivo é 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) ); }
A
sendEmail()
função emAcsService
executa as seguintes tarefas:- Chama a
http.post()
função e passa o assunto do email, a mensagem, o nome do cliente e o endereço de email do cliente para ela. Ahttp.post()
função retorna um observável RxJS que contém a resposta da chamada à API. - Manipula todos os
http.post()
erros retornados pela função usando o operador RxJScatchError
.
- Chama a
Agora vamos examinar como o aplicativo interage com o recurso de e-mail do ACS. Abra o arquivo acs.ts e localize a
sendEmail()
função. O caminho completo para o arquivo é server/typescript/acs.ts.A
sendEmail()
função executa as seguintes tarefas:Cria um novo
EmailClient
objeto e passa a cadeia de conexão ACS para ele (esse valor é recuperado daACS_CONNECTION_STRING
variável de ambiente).const emailClient = new EmailClient(connectionString);
Cria um novo
EmailMessage
objeto e passa as informações do remetente, assunto, mensagem e destinatário.const msgObject: EmailMessage = { senderAddress: process.env.ACS_EMAIL_ADDRESS as string, content: { subject: subject, plainText: message, }, recipients: { to: [ { address: customerEmailAddress, displayName: customerName, }, ], }, };
Envia o e-mail usando a
emailClient.beginSend()
função e retorna a resposta. Embora a função esteja enviando apenas para um destinatário neste exemplo, abeginSend()
função também pode ser usada para enviar para vários destinatários.const poller = await emailClient.beginSend(msgObject);
Aguarda que o
poller
objeto sinalize que foi concluído e envia a resposta ao chamador.
Explorando o código SMS
Volte para o arquivo email-sms-dialog.component.ts que você abriu anteriormente. O caminho completo para o arquivo é client/src/app/email-sms-dialog/email-sms-dialog.component.ts.
Localize a
sendSms()
função: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; } }
A
sendSMS()
função executa as seguintes tarefas:- Verifica se o sinalizador de
acsPhoneEnabled
recurso está definido comotrue
. Esse sinalizador verifica se aACS_PHONE_NUMBER
variável de ambiente tem um valor atribuído. - Se
acsPhoneEnabled
for true, aacsService.SendSms()
função será chamada e a mensagem SMS e o número de telefone do cliente serão passados. Como o banco de dados contém dados de amostra, aCUSTOMER_PHONE_NUMBER
variável de ambiente é usada em vez dethis.data.customerPhoneNumber
. Em um aplicativo do mundo real, othis.data.customerPhoneNumber
valor seria usado. - Subscreve a
sendSms()
função noacsService
serviço. Essa função retorna um RxJS observável que contém a resposta do serviço do lado do cliente. - Se a mensagem SMS foi enviada com êxito, ela define a
smsSent
propriedade comotrue
.
- Verifica se o sinalizador de
Abra acs.service.ts e localize a
sendSms()
função. O caminho completo para o arquivo é 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) ); }
A
sendSms()
função executa as seguintes tarefas:- Chama a
http.post()
função e passa a mensagem e o número de telefone do cliente para ela. Ahttp.post()
função retorna um observável RxJS que contém a resposta da chamada à API. - Manipula todos os
http.post()
erros retornados pela função usando o operador RxJScatchError
.
- Chama a
Por fim, vamos examinar como o aplicativo interage com o recurso ACS SMS. Abra o arquivo acs.ts . O caminho completo para o arquivo é server/typescript/acs.ts e localize a
sendSms()
função.A
sendSms()
função executa as seguintes tarefas:Cria um novo
SmsClient
objeto e passa a cadeia de conexão ACS para ele (esse valor é recuperado daACS_CONNECTION_STRING
variável de ambiente).const smsClient = new SmsClient(connectionString);
Chama a
smsClient.send()
função e passa o número de telefone do ACS (from
), o número de telefone do cliente (to
) e a mensagem SMS:const sendResults = await smsClient.send({ from: process.env.ACS_PHONE_NUMBER as string, to: [customerPhoneNumber], message: message }); return sendResults;
Retorna a resposta ao chamador.
Você pode saber mais sobre a funcionalidade de e-mail e SMS do ACS nos seguintes artigos:
Antes de passar para o próximo exercício, vamos examinar os principais conceitos abordados neste exercício:
- O arquivo acs.service.ts encapsula a funcionalidade de email e SMS do ACS usada pelo aplicativo do lado do cliente. Ele lida com as chamadas de API para o servidor e retorna a resposta para o chamador.
- A API do lado do servidor usa o ACS
EmailClient
eSmsClient
objetos para enviar mensagens de email e SMS.
Agora que você aprendeu como as mensagens de email e SMS podem ser enviadas, vamos mudar nosso foco para a integração de dados organizacionais no aplicativo.
Dados organizacionais: criando um registro de aplicativo de ID do Microsoft Entra
Aumente a produtividade do usuário integrando dados organizacionais (e-mails, arquivos, bate-papos e eventos de calendário) diretamente em seus aplicativos personalizados. Usando as APIs do Microsoft Graph e a ID do Microsoft Entra, você pode recuperar e exibir dados relevantes em seus aplicativos, reduzindo a necessidade de os usuários alternarem o contexto. Seja fazendo referência a um email enviado a um cliente, revisando uma mensagem do Teams ou acessando um arquivo, os usuários podem encontrar rapidamente as informações de que precisam sem sair do aplicativo, simplificando o processo de tomada de decisão.
Neste exercício, você vai:
- Crie um registro de aplicativo de ID do Microsoft Entra para que o Microsoft Graph possa acessar dados organizacionais e trazê-los para o aplicativo.
- Localize
team
echannel
IDs do Microsoft Teams que são necessários para enviar mensagens de chat para um canal específico. - Atualize o arquivo .env do projeto com valores do registro do aplicativo ID do Microsoft Entra.
Criar um registro de aplicativo do Microsoft Entra ID
Acesse o portal do Azure e selecione ID do Microsoft Entra.
Selecione Gerenciar -->Registros de aplicativo seguido de + Novo registro.
Preencha os detalhes do formulário de registro do novo aplicativo, conforme mostrado abaixo, e selecione Registrar:
- Nome: microsoft-graph-app
- Tipos de conta com suporte: contas em qualquer diretório organizacional (qualquer locatário de ID do Microsoft Entra - Multilocatário)
- URI de Redirecionamento:
- Selecione SPA (aplicativo de página única) e insira
http://localhost:4200
o campo URI de redirecionamento.
- Selecione SPA (aplicativo de página única) e insira
- Selecione Registrar para criar o registro do aplicativo.
Selecione Visão geral no menu de recursos e copie o valor para a
Application (client) ID
área de transferência.
Atualizar o arquivo .env do projeto
Abra o arquivo .env em seu editor e atribua o
Application (client) ID
valor aENTRAID_CLIENT_ID
.ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE>
Se você quiser habilitar a capacidade de enviar uma mensagem do aplicativo para um Canal do Teams, entre no Microsoft Teams usando sua conta de locatário de desenvolvimento do Microsoft 365 (isso é mencionado nos pré-requisitos do tutorial).
Depois de fazer login, expanda uma equipe e encontre um canal para o qual deseja enviar mensagens no aplicativo. Por exemplo, você pode selecionar a equipe da empresa e o canal Geral (ou qualquer equipe/canal que você gostaria de usar).
No cabeçalho da equipe, clique nos três pontos (...) e selecione Obter link para a equipe.
No link que aparece na janela pop-up, o ID da equipe é a sequência de letras e números após
team/
. Por exemplo, no link "https://teams.microsoft.com/l/team/19%3ae9b9.../", o ID da equipe é 19%3ae9b9... até o seguinte/
caractere.Copie a ID da equipe e atribua-a no
TEAM_ID
arquivo .env.No cabeçalho do canal, clique nos três pontos (...) e selecione Obter link para o canal.
No link que aparece na janela pop-up, o ID do canal é a sequência de letras e números após
channel/
. Por exemplo, no link "https://teams.microsoft.com/l/channel/19%3aQK02.../", o ID do canal é 19%3aQK02... até o seguinte/
caractere.Copie o ID do canal e atribua-o no
CHANNEL_ID
arquivo .env .Salve o arquivo env antes de continuar.
Iniciar/reiniciar os servidores de aplicativos e API
Execute uma das seguintes etapas com base nos exercícios concluídos até este ponto:
Se você iniciou o banco de dados, o servidor de API e o servidor Web em um exercício anterior, será necessário interromper o servidor de API e o servidor Web e reiniciá-los para selecionar as alterações do arquivo .env . Você pode deixar o banco de dados em execução.
Localize as janelas do terminal que executam o servidor de API e o servidor web e pressione CTRL + C para pará-las. Inicie-os novamente digitando
npm start
em cada janela do terminal e pressionando Enter. Continue para o próximo exercício.Se você ainda não iniciou o banco de dados, o servidor de API e o servidor Web, conclua as seguintes etapas:
Nas etapas a seguir, você criará três janelas de terminal no Visual Studio Code.
Clique com o botão direito do mouse no arquivo .env na lista de arquivos do Visual Studio Code e selecione Abrir no Terminal Integrado. Certifique-se de que seu terminal esteja na raiz do projeto - openai-acs-msgraph - antes de continuar.
Escolha uma das seguintes opções para iniciar o banco de dados PostgreSQL:
Se você tiver o Docker Desktop instalado e em execução, execute
docker-compose up
na janela do terminal e pressione Enter.Se você tiver o Podman com o podman-compose instalado e em execução, execute
podman-compose up
na janela do terminal e pressione Enter.Para executar o contêiner do PostgreSQL diretamente usando o Docker Desktop, o Podman, o nerdctl ou outro tempo de execução do contêiner que você instalou, execute o seguinte comando na janela do terminal:
Subsistema Mac, Linux ou 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 com 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
Depois que o contêiner do banco de dados for iniciado, pressione o + ícone na barra de ferramentas do Terminal do Visual Studio Code para criar uma segunda janela de terminal.
cd
na pasta server/typescript e execute os comandos a seguir para instalar as dependências e iniciar o servidor de API.npm install
npm start
Pressione o + ícone novamente na barra de ferramentas do Terminal do Visual Studio Code para criar uma terceira janela de terminal.
cd
na pasta do cliente e execute os comandos a seguir para instalar as dependências e iniciar o servidor Web.npm install
npm start
Um navegador será iniciado e você será direcionado para http://localhost:4200.
Dados organizacionais: Conectando um usuário e obtendo um token de acesso
Os usuários precisam se autenticar com a ID do Microsoft Entra para que o Microsoft Graph acesse os dados organizacionais. Neste exercício, você verá como o componente do mgt-login
Microsoft Graph Toolkit pode ser usado para autenticar usuários e recuperar um token de acesso. O token de acesso pode ser usado para fazer chamadas para o Microsoft Graph.
Observação
Se você não estiver familiarizado com o Microsoft Graph, poderá saber mais sobre ele no roteiro de aprendizagem Conceitos básicos do Microsoft Graph.
Neste exercício, você vai:
- Saiba como associar um aplicativo de ID do Microsoft Entra ao Kit de Ferramentas do Microsoft Graph para autenticar usuários e recuperar dados organizacionais.
- Saiba mais sobre a importância dos escopos.
- Saiba como o componente mgt-login do Microsoft Graph Toolkit pode ser usado para autenticar usuários e recuperar um token de acesso.
Usando o recurso de login
No exercício anterior, você criou um registro de aplicativo na ID do Microsoft Entra e iniciou o servidor de aplicativos e o servidor de API. Você também atualizou os seguintes valores no
.env
arquivo (TEAM_ID
eCHANNEL_ID
são opcionais):ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE> TEAM_ID=<TEAMS_TEAM_ID> CHANNEL_ID=<TEAMS_CHANNEL_ID>
Certifique-se de ter concluído o exercício anterior antes de continuar.
Volte para o navegador (http://localhost:4200), selecione Entrar no cabeçalho e entre usando uma conta de usuário administrador do seu locatário Microsoft 365 Developer.
Dica
Entre com sua conta de administrador de locatário de desenvolvedor do Microsoft 365. Você pode exibir outros usuários em seu locatário de desenvolvedor acessando o Centro de administração do Microsoft 365.
Se você estiver entrando no aplicativo pela primeira vez, será solicitado que você concorde com as permissões solicitadas pelo aplicativo. Você aprenderá mais sobre essas permissões (também chamadas de "escopos") na próxima seção à medida que explora o código. Selecione Aceitar para continuar.
Depois de fazer login, você verá o nome do usuário exibido no cabeçalho.
Explorando o código de login
Agora que você entrou, vamos examinar o código usado para conectar o usuário e recuperar um token de acesso e um perfil de usuário. Você aprenderá sobre o componente Web mgt-login que faz parte do Microsoft Graph Toolkit.
Dica
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Abra client/package.json e observe que os
@microsoft/mgt
pacotes e@microsoft/mgt-components
estão incluídos nas dependências. O@microsoft/mgt
pacote contém recursos de provedor MSAL (Biblioteca de Autenticação da Microsoft) e componentes Web, como mgt-login e outros que podem ser usados para conectar usuários e recuperar e exibir dados organizacionais.Abra client/src/main.ts e observe as seguintes importações do
@microsoft/mgt-components
pacote. Os símbolos importados são usados para registrar os componentes do Microsoft Graph Toolkit usados no aplicativo.import { registerMgtLoginComponent, registerMgtSearchResultsComponent, registerMgtPersonComponent, } from '@microsoft/mgt-components';
Role até a parte inferior do arquivo e observe o seguinte código:
registerMgtLoginComponent(); registerMgtSearchResultsComponent(); registerMgtPersonComponent();
Esse código registra os
mgt-login
componentes ,mgt-search-results
emgt-person
Web e os habilita para uso no aplicativo.Para usar o componente mgt-login para conectar usuários, a ID do cliente do aplicativo ID do Microsoft Entra (armazenada no arquivo .env como
ENTRAID_CLIENT_ID
) precisa ser referenciada e usada.Abra graph.service.ts e localize a
init()
função. O caminho completo para o arquivo é client/src/app/core/graph.service.ts. Você verá a seguinte importação e 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'); } }
Esse código cria um novo
Msal2Provider
objeto, passando a ID do cliente da ID do Microsoft Entra do registro do aplicativo e o para oscopes
qual o aplicativo solicitará acesso. Elesscopes
são usados para solicitar acesso aos recursos do Microsoft Graph que o aplicativo acessará. Depois que oMsal2Provider
objeto é criado, ele é atribuído aoProviders.globalProvider
objeto, que é usado pelos componentes do Microsoft Graph Toolkit para recuperar dados do Microsoft Graph.Abra header.component.html em seu editor e localize o componente mgt-login . O caminho completo para o arquivo é client/src/app/header/header.component.html.
@if (this.featureFlags.microsoft365Enabled) { <mgt-login class="mgt-dark" (loginCompleted)="loginCompleted()"></mgt-login> }
O componente mgt-login permite a entrada do usuário e fornece acesso a um token usado com o Microsoft Graph. Após a entrada bem-sucedida, o evento é disparado, o
loginCompleted
que chama aloginCompleted()
função. Embora o mgt-login seja usado em um componente Angular neste exemplo, ele é compatível com qualquer aplicativo da Web.A exibição do componente mgt-login depende do
featureFlags.microsoft365Enabled
valor que está sendo definido comotrue
. Esse sinalizador personalizado verifica a presença da variável de ambiente para confirmar se o aplicativo está configurado corretamente e pode ser autenticado na ID doENTRAID_CLIENT_ID
Microsoft Entra. O sinalizador é adicionado para acomodar casos em que os usuários optam por concluir apenas os exercícios de IA ou Comunicação dentro do tutorial, em vez de seguir toda a sequência de exercícios.Abra header.component.ts e localize a
loginCompleted
função. Essa função é chamada quando ologinCompleted
evento é emitido e manipula a recuperação do perfil do usuário conectado usandoProviders.globalProvider
.async loginCompleted() { const me = await Providers.globalProvider.graph.client.api('me').get(); this.userLoggedIn.emit(me); }
Neste exemplo, uma chamada está sendo feita para a API do Microsoft Graph
me
para recuperar o perfil do usuário (me
representa o usuário conectado atual). Athis.userLoggedIn.emit(me)
instrução de código emite um evento do componente para passar os dados de perfil para o componente pai. O componente pai é app.component.ts arquivo nesse caso, que é o componente raiz do aplicativo.Para saber mais sobre o componente mgt-login , visite a documentação do Microsoft Graph Toolkit .
Agora que você fez logon no aplicativo, vamos ver como os dados organizacionais podem ser recuperados.
Dados organizacionais: recuperando arquivos, chats e enviando mensagens para o Teams
No ambiente digital atual, os usuários trabalham com uma ampla gama de dados organizacionais, incluindo e-mails, bate-papos, arquivos, eventos de calendário e muito mais. Isso pode levar a mudanças frequentes de contexto, alternando entre tarefas ou aplicativos, o que pode interromper o foco e reduzir a produtividade. Por exemplo, um usuário que trabalha em um projeto pode precisar alternar de seu aplicativo atual para o Outlook para encontrar detalhes cruciais em um email ou alternar para o OneDrive for Business para encontrar um arquivo relacionado. Essa ação de ida e volta interrompe o foco e desperdiça tempo que poderia ser melhor gasto na tarefa em questão.
Para aumentar a eficiência, você pode integrar dados organizacionais diretamente nos aplicativos que os usuários usam todos os dias. Ao trazer dados organizacionais para seus aplicativos, os usuários podem acessar e gerenciar informações com mais facilidade, minimizando as mudanças de contexto e melhorando a produtividade. Além disso, essa integração fornece informações e contexto valiosos, permitindo que os usuários tomem decisões informadas e trabalhem com mais eficiência.
Neste exercício, você vai:
- Saiba como o componente Web mgt-search-results no Microsoft Graph Toolkit pode ser usado para pesquisar arquivos.
- Saiba como chamar o Microsoft Graph diretamente para recuperar arquivos do OneDrive for Business e mensagens de chat do Microsoft Teams.
- Entenda como enviar mensagens de chat para canais do Microsoft Teams usando o Microsoft Graph.
Usando o recurso de dados organizacionais
Em um exercício anterior, você criou um registro de aplicativo na ID do Microsoft Entra e iniciou o servidor de aplicativos e o servidor de API. Você também atualizou os seguintes valores no
.env
arquivo.ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE> TEAM_ID=<TEAMS_TEAM_ID> CHANNEL_ID=<TEAMS_CHANNEL_ID>
Certifique-se de ter concluído o exercício anterior antes de continuar.
Volte para o navegador (http://localhost:4200). Se você ainda não tiver entrado, selecione Entrar no cabeçalho e entre com um usuário do seu locatário Microsoft 365 Developer.
Observação
Além de autenticar o usuário, o componente Web mgt-login também recupera um token de acesso que pode ser usado pelo Microsoft Graph para acessar arquivos, chats, emails, eventos de calendário e outros dados organizacionais. O token de acesso contém os escopos (permissões), como
Chat.ReadWrite
,Files.Read.All
e outros que você viu 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'] });
Selecione Exibir Conteúdo Relacionado para a linha Adatum Corporation na grade de dados. Isso fará com que dados organizacionais, como arquivos, chats, emails e eventos de calendário, sejam recuperados usando o Microsoft Graph. Depois que os dados forem carregados, eles serão exibidos abaixo da grade de dados em uma interface com guias. É importante mencionar que você pode não ver nenhum dado neste momento, pois ainda não adicionou arquivos, chats, emails ou eventos de calendário para o usuário em seu locatário de desenvolvedor do Microsoft 365. Vamos corrigir isso na próxima etapa.
Seu locatário do Microsoft 365 pode não ter nenhum dado organizacional relacionado para a Adatum Corporation neste estágio. Para adicionar alguns dados de exemplo, execute pelo menos uma das seguintes ações:
Adicione arquivos visitando https://onedrive.com e entrando usando suas credenciais de locatário do Microsoft 365 Developer.
- Selecione Meus arquivos no painel de navegação à esquerda.
- Selecione + Adicionar novo e, em seguida, Upload de pasta no menu.
- Selecione a pasta openai-acs-msgraph/documentos do cliente no projeto que você clonou.
Adicione mensagens de chat e eventos de calendário visitando https://teams.microsoft.com e entrando usando suas credenciais de locatário do Microsoft 365 Developer.
Selecione Teams no painel de navegação à esquerda.
Selecione uma equipe e um canal.
Selecione Iniciar uma postagem.
Insira Novo pedido feito para a Adatum Corporation para o assunto e qualquer texto adicional que você gostaria de adicionar no corpo da mensagem. Selecione o botão Postar.
Sinta-se à vontade para adicionar mensagens de chat adicionais que mencionam outras empresas usadas no aplicativo, como Adventure Works Cycles, Contoso Pharmaceuticals e Tailwind Traders.
Selecione Calendário no painel de navegação à esquerda.
Selecione Nova reunião.
Digite "Reunir-se com a Adatum Corporation sobre o cronograma do projeto" para o título e o corpo.
Selecione Salvar.
Adicione emails visitando https://outlook.com e entrando usando suas credenciais de locatário do Microsoft 365 Developer.
Selecione Novo e-mail.
Digite seu endereço de e-mail pessoal no campo Para .
Digite Novo pedido feito para a Adatum Corporation para o assunto e qualquer coisa que você gostaria para o corpo.
Selecione Enviar.
Volte para o aplicativo no navegador e atualize a página. Selecione Exibir conteúdo relacionado novamente para a linha Adatum Corporation . Agora você deve ver os dados exibidos nas guias, dependendo de quais tarefas você executou na etapa anterior.
Vamos explorar o código que habilita o recurso de dados organizacionais no aplicativo. Para recuperar os dados, a parte do lado do cliente do aplicativo usa o token de acesso recuperado pelo componente mgt-login que você examinou anteriormente para fazer chamadas para APIs do Microsoft Graph.
Explorando o código de pesquisa de arquivos
Dica
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Vamos começar examinando como os dados de arquivo são recuperados do OneDrive for Business. Abra files.component.html e reserve um momento para examinar o código. O caminho completo para o arquivo é client/src/app/files/files.component.html.
Localize o componente mgt-search-results e observe os seguintes atributos:
<mgt-search-results class="search-results" entity-types="driveItem" [queryString]="searchText" (dataChange)="dataChange($any($event))" />
O componente mgt-search-results faz parte do Microsoft Graph Toolkit e, como o nome indica, é usado para exibir resultados de pesquisa do Microsoft Graph. O componente usa os seguintes recursos neste exemplo:
O
class
atributo é usado para especificar que asearch-results
classe CSS deve ser aplicada ao componente.O
entity-types
atributo é usado para especificar o tipo de dados a serem pesquisados. Nesse caso, o valor édriveItem
usado para pesquisar arquivos no OneDrive for Business.O
queryString
atributo é usado para especificar o termo de pesquisa. Nesse caso, o valor é vinculado àsearchText
propriedade que é passada para o componente de arquivos quando o usuário seleciona Exibir conteúdo relacionado para uma linha na grade de dados. Os colchetes ao redorqueryString
indicam que a propriedade está associada aosearchText
valor.O
dataChange
evento é acionado quando os resultados da pesquisa são alterados. Nesse caso, uma função de cliente chamadadataChange()
é chamada no componente de arquivos e os dados do evento são passados para a função. Os parênteses indicamdataChange
que o evento está vinculado àdataChange()
função.Como nenhum modelo personalizado é fornecido, o modelo padrão integrado
mgt-search-results
é usado para exibir os resultados da pesquisa.
Uma alternativa ao uso de componentes como mgt-search-results é chamar APIs do Microsoft Graph diretamente usando código. Para ver como isso funciona, abra o arquivo graph.service.ts e localize a
searchFiles()
função. O caminho completo para o arquivo é client/src/app/core/graph.service.ts.Você notará que um
query
parâmetro é passado para a função. Esse é o termo de pesquisa que é passado quando o usuário seleciona Exibir Conteúdo Relacionado para uma linha na grade de dados. Se nenhum termo de pesquisa for passado, uma matriz vazia será retornada.async searchFiles(query: string) { const files: DriveItem[] = []; if (!query) return files; ... }
Em seguida, é criado um filtro que define o tipo de pesquisa a ser executada. Nesse caso, o código está procurando arquivos no OneDrive for Business, portanto,
driveItem
é usado exatamente como você viu anteriormente com omgt-search-results
componente. Isso é o mesmo que passardriveItem
paraentity-types
no componente mgt-search-results que você viu anteriormente. Oquery
parâmetro é então adicionado aoqueryString
filtro junto comContentType:Document
.const filter = { "requests": [ { "entityTypes": [ "driveItem" ], "query": { "queryString": `${query} AND ContentType:Document` } } ] };
Em seguida, uma chamada é feita para a API do
/search/query
Microsoft Graph usando aProviders.globalProvider.graph.client.api()
função. Ofilter
objeto é passado para apost()
função que envia os dados para a API.const searchResults = await Providers.globalProvider.graph.client.api('/search/query').post(filter);
Os resultados da pesquisa são então iterados para localizar
hits
. Cadahit
um contém informações sobre um documento que foi encontrado. Uma propriedade chamadaresource
contém os metadados do documento e é adicionada àfiles
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
matriz é então retornada ao chamador.return files;
Olhando através deste código, você pode ver que o componente da web mgt-search-results que você explorou anteriormente faz muito trabalho para você e reduz significativamente a quantidade de código que você precisa escrever! No entanto, pode haver cenários em que você deseja chamar o Microsoft Graph diretamente para ter mais controle sobre os dados enviados para a API ou como os resultados são processados.
Abra o arquivo files.component.ts e localize a
search()
função. O caminho completo para o arquivo é client/src/app/files/files.component.ts.Embora o corpo dessa função seja comentado devido ao componente mgt-search-results que está sendo usado, a função pode ser usada para fazer a chamada para o Microsoft Graph quando o usuário seleciona Exibir Conteúdo Relacionado para uma linha na grade de dados. A
search()
função chamasearchFiles()
graph.service.ts e passa oquery
parâmetro para ela (o nome da empresa neste exemplo). Os resultados da pesquisa são então atribuídos àdata
propriedade do componente.override async search(query: string) { this.data = await this.graphService.searchFiles(query); }
O componente de arquivos pode usar a
data
propriedade para exibir os resultados da pesquisa. Você pode lidar com isso usando associações HTML personalizadas ou usando outro controle do Microsoft Graph Toolkit chamadomgt-file-list
. Aqui está um exemplo de associação dadata
propriedade a uma das propriedades do componente nomeadafiles
e manipulação doitemClick
evento à medida que o usuário interage com um arquivo.<mgt-file-list (itemClick)="itemClick($any($event))" [files]="data"></mgt-file-list>
Se você optar por usar o componente mgt-search-results mostrado anteriormente ou escrever um código personalizado para chamar o Microsoft Graph dependerá do seu cenário específico. Neste exemplo, o componente mgt-search-results é usado para simplificar o código e reduzir a quantidade de trabalho que você precisa fazer.
Explorando o código de pesquisa de mensagens de chat do Teams
Volte para graph.service.ts e localize a
searchChatMessages()
função. Você verá que é semelhante àsearchFiles()
função que você examinou anteriormente.- Ele posta dados de filtro na API do
/search/query
Microsoft Graph e converte os resultados em uma matriz de objetos que têm informações sobre oteamId
,channelId
emessageId
que correspondem ao termo de pesquisa. - Para recuperar as mensagens do canal do Teams, uma segunda chamada é feita para a
/teams/${chat.teamId}/channels/${chat.channelId}/messages/${chat.messageId}
API e oteamId
,channelId
emessageId
são passados. Isso retorna os detalhes completos da mensagem. - Tarefas de filtragem adicionais são executadas e as mensagens resultantes são retornadas para
searchChatMessages()
o chamador.
- Ele posta dados de filtro na API do
Abra o arquivo chats.component.ts e localize a
search()
função. O caminho completo para o arquivo é client/src/app/chats/chats.component.ts. Asearch()
função chamasearchChatMessages()
graph.service.ts e passa oquery
parâmetro para ele.override async search(query: string) { this.data = await this.graphService.searchChatMessages(query); }
Os resultados da pesquisa são atribuídos à
data
propriedade do componente e a vinculação de dados é usada para iterar por meio da matriz de resultados e renderizar os dados. Este exemplo usa um componente de cartão Material angular para exibir os resultados da pesquisa.@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> }
Enviando uma mensagem para um canal do Microsoft Teams
Além de pesquisar mensagens de bate-papo do Microsoft Teams, o aplicativo também permite que um usuário envie mensagens para um canal do Microsoft Teams. Isso pode ser feito chamando o
/teams/${teamId}/channels/${channelId}/messages
ponto de extremidade do Microsoft Graph.No código a seguir, você verá que uma URL é criada que inclui os
teamId
valores echannelId
. Os valores de variável de ambiente são usados para a ID da equipe e a ID do canal neste exemplo, mas esses valores também podem ser recuperados dinamicamente usando o Microsoft Graph. Abody
constante contém a mensagem a ser enviada. Uma solicitação POST é feita e os resultados são retornados ao chamador.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' }; }
Aproveitar esse tipo de funcionalidade no Microsoft Graph fornece uma ótima maneira de aprimorar a produtividade do usuário, permitindo que os usuários interajam com o Microsoft Teams diretamente do aplicativo que já estão usando.
Dados organizacionais: recuperar e-mails e eventos da agenda
No exercício anterior, você aprendeu a recuperar arquivos do OneDrive for Business e chats do Microsoft Teams usando o Microsoft Graph e o componente mgt-search-results do Microsoft Graph Toolkit. Você também aprendeu a enviar mensagens para canais do Microsoft Teams. Neste exercício, você aprenderá a recuperar mensagens de email e eventos de calendário do Microsoft Graph e integrá-los ao aplicativo.
Neste exercício, você vai:
- Saiba como o componente Web mgt-search-results no Microsoft Graph Toolkit pode ser usado para pesquisar emails e eventos de calendário.
- Saiba como personalizar o componente mgt-search-results para renderizar os resultados da pesquisa de maneira personalizada.
- Saiba como chamar o Microsoft Graph diretamente para recuperar emails e eventos de calendário.
Explorando o código de pesquisa de mensagens de e-mail
Dica
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Em um exercício anterior, você criou um registro de aplicativo na ID do Microsoft Entra e iniciou o servidor de aplicativos e o servidor de API. Você também atualizou os seguintes valores no
.env
arquivo.ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE> TEAM_ID=<TEAMS_TEAM_ID> CHANNEL_ID=<TEAMS_CHANNEL_ID>
Certifique-se de ter concluído o exercício anterior antes de continuar.
Abra emails.component.html e reserve um momento para examinar o código. O caminho completo para o arquivo é client/src/app/emails/emails.component.html.
Localize o 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 exemplo do componente mgt-search-results é configurado da mesma forma que o que você viu anteriormente. A única diferença é que o
entity-types
atributo é definido paramessage
ser usado para pesquisar mensagens de e-mail e um modelo vazio é fornecido.- O
class
atributo é usado para especificar que asearch-results
classe CSS deve ser aplicada ao componente. - O
entity-types
atributo é usado para especificar o tipo de dados a serem pesquisados. Nesse caso, o valor émessage
. - O
queryString
atributo é usado para especificar o termo de pesquisa. - O
dataChange
evento é acionado quando os resultados da pesquisa são alterados. A função do componente emails é chamada, os resultados são passadosdataChange()
para ele e uma propriedade chamadadata
é atualizada no componente. - Um modelo vazio é definido para o componente. Esse tipo de modelo é normalmente usado para definir como os resultados da pesquisa serão renderizados. No entanto, neste cenário, estamos dizendo ao componente para não renderizar nenhum dado de mensagem. Em vez disso, renderizaremos os dados usando a vinculação de dados padrão (Angular é usado neste caso, mas você pode usar qualquer biblioteca/estrutura que desejar).
- O
Procure abaixo o componente mgt-search-results no emails.component.html para encontrar as ligações de dados usadas para renderizar as mensagens de e-mail. Este exemplo itera por meio da propriedade e grava o assunto do
data
email, a visualização do corpo e um link para exibir a mensagem de email completa.@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> }
Além de usar o componente mgt-search-results para recuperar mensagens, o Microsoft Graph fornece várias APIs que também podem ser usadas para pesquisar emails. A
/search/query
API que você viu anteriormente certamente poderia ser usada, mas uma opção mais direta é amessages
API.Para ver como chamar essa API, volte para graph.service.ts e localize a
searchEmailMessages()
função. Ele cria uma URL que pode ser usada para chamar omessages
ponto de extremidade do Microsoft Graph e atribui oquery
valor ao$search
parâmetro. Em seguida, o código faz uma solicitação GET e retorna os resultados para o chamador. O$search
operador pesquisa oquery
valor nos campos assunto, corpo e remetente automaticamente.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; }
O componente de e-mails localizado em emails.component.ts chamadas
searchEmailMessages()
e exibe os resultados na interface do usuário.override async search(query: string) { this.data = await this.graphService.searchEmailMessages(query); }
Explorando o código de pesquisa de eventos do calendário
A pesquisa de eventos de calendário também pode ser realizada usando o componente mgt-search-results . Ele pode lidar com a renderização dos resultados para você, mas você também pode definir seu próprio modelo, que verá mais adiante neste exercício.
Abra calendar-events.component.html e reserve um momento para examinar o código. O caminho completo para o arquivo é client/src/app/calendar-events/calendar-events.component.html. Você verá que é muito semelhante aos componentes de arquivos e e-mails que você examinou 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 exemplo do componente mgt-search-results é configurado da mesma forma que os que você viu anteriormente. A única diferença é que o
entity-types
atributo é definido paraevent
que é usado para pesquisar eventos de calendário e um modelo vazio é fornecido.- O
class
atributo é usado para especificar que asearch-results
classe CSS deve ser aplicada ao componente. - O
entity-types
atributo é usado para especificar o tipo de dados a serem pesquisados. Nesse caso, o valor éevent
. - O
queryString
atributo é usado para especificar o termo de pesquisa. - O
dataChange
evento é acionado quando os resultados da pesquisa são alterados. A função do componente de evento de calendário é chamada, os resultados são passadosdataChange()
para ele e uma propriedade chamadadata
é atualizada no componente. - Um modelo vazio é definido para o componente. Nesse cenário, estamos dizendo ao componente para não renderizar nenhum dado. Em vez disso, renderizaremos os dados por conta própria usando a vinculação de dados padrão.
- O
Imediatamente abaixo do
mgt-search-results
componente em calendar-events.component.html você encontrará as vinculações de dados usadas para renderizar os eventos do calendário. Este exemplo itera peladata
propriedade e grava a data de início, a hora e o assunto do evento. As funções personalizadas incluídas no componente, comodayFromDateTime()
etimeRangeFromEvent()
são chamadas para formatar os dados corretamente. As associações HTML também incluem um link para exibir o evento de calendário no Outlook e o local do evento, se especificado.@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> }
Além de pesquisar eventos de calendário usando a API, o Microsoft Graph também fornece uma
events
API que também pode ser usada para pesquisar eventos desearch/query
calendário. Localize asearchCalendarEvents()
função em graph.service.ts.A
searchCalendarEvents()
função cria valores de data/hora de início e término que são usados para definir o período de tempo a ser pesquisado. Em seguida, ele cria uma URL que pode ser usada para chamar oevents
ponto de extremidade do Microsoft Graph e inclui o parâmetro e asquery
variáveis de data/hora de início e término. Uma solicitação GET é feita e os resultados são retornados ao chamador.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; }
Veja um detalhamento do URL criado:
- A
/me/events
parte da URL é usada para especificar que os eventos do usuário conectado devem ser recuperados. - Os
startdatetime
parâmetros eenddatetime
são usados para definir o período de tempo para pesquisar. Nesse caso, a pesquisa retornará eventos que começam nos próximos 7 dias. - O
$filter
parâmetro de consulta é usado para filtrar os resultados peloquery
valor (o nome da empresa selecionado na grade de dados neste caso). Acontains()
função é usada para procurar oquery
valor nasubject
propriedade do evento do calendário. - O
$orderby
parâmetro de consulta é usado para ordenar os resultados pelastart/dateTime
propriedade.
- A
Depois que o
url
é criado, uma solicitação GET é feita para a API do Microsoft Graph usando o valor deurl
e os resultados são retornados ao chamador.Assim como acontece com os componentes anteriores, o componente de eventos de calendário (calendar-events.component.ts arquivo) chama
search()
e exibe os resultados.override async search(query: string) { this.data = await this.graphService.searchCalendarEvents(query); }
Observação
Você também pode fazer chamadas do Microsoft Graph de uma API personalizada ou de um aplicativo do lado do servidor. Veja o tutorial a seguir para ver um exemplo de chamada de uma API do Microsoft Graph de uma função do Azure.
Agora você viu um exemplo de como usar o Microsoft Graph para recuperar arquivos, chats, mensagens de email e eventos de calendário. Os mesmos conceitos também podem ser aplicados a outras APIs do Microsoft Graph. Por exemplo, você pode usar a API de usuários do Microsoft Graph para pesquisar usuários em sua organização. Você também pode usar a API de grupos do Microsoft Graph para pesquisar grupos em sua organização. Você pode exibir a lista completa de APIs do Microsoft Graph na documentação.
Parabéns!
Você concluiu este tutorial
Parabéns! Neste tutorial, você aprendeu como:
- O Azure OpenAI pode ser usado para aumentar a produtividade do usuário.
- Os Serviços de Comunicação do Azure podem ser usados para integrar recursos de comunicação.
- As APIs e os componentes do Microsoft Graph podem ser usados para recuperar e exibir dados organizacionais.
Ao usar essas tecnologias, você pode criar soluções eficazes que aumentam a produtividade do usuário, minimizando as mudanças de contexto e fornecendo as informações necessárias para a tomada de decisões.
Limpar os recursos do Azure
Limpe seus recursos do Azure para evitar mais cobranças em sua conta. Acesse o portal do Azure e exclua os seguintes recursos:
- Recurso de Pesquisa de IA do Azure
- Recurso de armazenamento do Azure
- Recurso OpenAI do Azure (certifique-se de excluir seus modelos primeiro e, em seguida, o recurso OpenAI do Azure)
- Recurso dos Serviços de Comunicação do Azure
Próximas etapas
Documentação
- Documentação do OpenAI do Azure
- OpenAI do Azure em seus dados
- Documentação dos Serviços de Comunicação do Azure
- Documentação do Microsoft Graph
- Documentação do Microsoft Graph Toolkit
- Documentação do desenvolvedor do Microsoft Teams
Conteúdo dos Treinamentos
- Aplicar a engenharia de prompt com o Serviço OpenAI do Azure
- Introdução ao Serviço OpenAI do Azure
- Introdução aos Serviços de Comunicação do Azure
- Conceitos básicos do Microsoft Graph
- Curso em vídeo: Conceitos básicos do Microsoft Graph para iniciantes
- Explore cenários do Microsoft Graph para desenvolvimento de JavaScript
- Explore cenários do Microsoft Graph para desenvolvimento do ASP.NET Core
- Introdução ao Microsoft Graph Toolkit
- Criar e implantar aplicativos para o Microsoft Teams usando o Kit de Ferramentas do Teams para Visual Studio Code
Tem algum problema com essa seção? Se tiver, envie seus comentários para que possamos melhorar esta seção.