Integrar o OpenAI, a comunicação e os recursos de dados organizacionais em um aplicativo de linha de negócios
Nível: Intermediário
Este tutorial demonstra como o Azure OpenAI, Serviços de Comunicação do Azure e o Microsoft Graph/Microsoft Graph Toolkit podem ser integrados a aplicativos lob (linha de negócios) para aumentar a produtividade do usuário, elevar a experiência do usuário e levar aplicativos LOB para o próximo nível.
- IA: permitir que os usuários façam perguntas em linguagem natural e convertam suas respostas para SQL que podem ser usadas para consultar um banco de dados, permitir que os usuários definam regras que podem ser usadas para gerar mensagens sms e email automaticamente e saiba como a linguagem natural pode ser usada para recuperar dados de suas próprias fontes de dados personalizadas. O OpenAI do Azure é usado para esses recursos.
- Comunicação: habilite a chamada telefônica no aplicativo aos clientes e a funcionalidade de Email/SMS usando Serviços de Comunicação do Azure.
- Dados organizacionais: efetuar pull de dados organizacionais relacionados que os usuários podem precisar (documentos, chats, emails, eventos de calendário) à medida que 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. Uma vez que 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 que os usuários gerenciem seus clientes e dados relacionados. Ele consiste em um front-end criado usando o TypeScript que chama APIs de back-end para recuperar dados, interagir com a funcionalidade de IA, enviar mensagens de email/SMS e efetuar pull de dados organizacionais. Aqui está uma visão geral da solução de aplicativo que você examinará 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 cenários diferentes.
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 seu interesse. O tutorial é dividido nas seguintes áreas de tópico:
- Clone o Exercício do Projeto (exercício obrigatório).
- Exercícios de IA: crie um recurso do Azure OpenAI 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 de 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 Microsoft Entra ID para que o Microsoft Graph e o Microsoft Graph Toolkit possam ser usados para autenticar e efetuar pull de dados organizacionais no aplicativo.
Pré-requisitos
- Nó – o nó 16+ e o npm 7+ serão usados para este projeto
- git
- Visual Studio Code (embora 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
- Microsoft Entra ID
- Serviços de Comunicação do Azure
- Serviço OpenAI do Azure
- 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 servidor necessário para executar o projeto, permitindo que você explore os recursos integrados relacionados à IA (inteligência artificial), comunicação e dados organizacionais. Além disso, o projeto serve como um recurso para orientá-lo a incorporar recursos semelhantes em seus próprios aplicativos.
Neste exercício, você vai:
- Clone o repositório 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 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.
- servidor: 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 tire um momento para analisar as chaves incluídas:
ENTRAID_CLIENT_ID= TEAM_ID= CHANNEL_ID= OPENAI_API_KEY= OPENAI_ENDPOINT= OPENAI_API_VERSION=2023-06-01-preview OPENAI_MODEL=gpt-35-turbo POSTGRES_USER= POSTGRES_PASSWORD= ACS_CONNECTION_STRING= ACS_PHONE_NUMBER= ACS_EMAIL_ADDRESS= CUSTOMER_EMAIL_ADDRESS= CUSTOMER_PHONE_NUMBER= API_PORT=3000 AZURE_COGNITIVE_SEARCH_ENDPOINT= AZURE_COGNITIVE_SEARCH_KEY= AZURE_COGNITIVE_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 saber como eles são criados. Selecione o botão Avançar abaixo para continuar ou ir para um exercício específico usando o sumário.
IA: criar um recurso openai do Azure e implantar um modelo
Para começar a usar o OpenAI do Azure 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 mensagens 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 do Serviço OpenAI do Azure.
Criar um recurso de serviço OpenAI do Azure
Visite o portal do Azure no navegador e entre.
Digite 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
Se você vir uma mensagem sobre como concluir um formulário de aplicativo para habilitar o Azure OpenAI em sua assinatura, selecione o link Clique aqui para solicitar acesso ao serviço OpenAI do Azure e preencha o formulário. Depois de concluir o formulário, você precisará aguardar a equipe do Azure OpenAI aprovar sua solicitação. Depois de receber seu aviso de aprovação, você pode voltar por este exercício e criar o recurso.
Embora este tutorial se concentre no OpenAI do Azure, se você tiver uma chave de API OpenAI e quiser usá-la enquanto estiver aguardando acesso ao Azure OpenAI, poderá ignorar esta seção e ir diretamente para a seção Atualizar o arquivo .env do Projeto abaixo. Atribua sua chave de API OpenAI ao
OPENAI_API_KEY
no arquivo .env (você pode ignorar quaisquer outras.env
instruções relacionadas ao OpenAI). Depois de ter acesso ao Azure OpenAI, reveja este exercício, crie o recurso e o modelo e atualize o arquivo .env com os valores do recurso Azure OpenAI.Execute as seguintes tarefas:
- Selecione sua assinatura do Azure.
- Selecione o grupo de recursos a ser usado (crie um novo, se necessário).
- Selecione a região que você deseja usar.
- 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 Examinar + enviar . Selecione Criar.
Depois que o recurso do Azure OpenAI for criado, navegue até ele e selecione Chaves e Ponto de Extremidade na seção Gerenciamento de Recursos .
Localize os valores KEY 1 e Endpoint . Você usará os dois valores na próxima seção para copiá-los para um arquivo local.
Selecione Implantações de modelo na seção Gerenciamento de Recursos .
Selecione o botão Gerenciar Implantações para acessar o Azure OpenAI Studio.
Selecione Criar nova implantação na barra de ferramentas.
Insira os valores a seguir:
- Modelo: gpt-35-turbo.
- Versão do modelo: atualização automática para padrão.
- Nome da implantação: gpt-35-turbo.
Observação
O Azure OpenAI dá suporte a vários tipos diferentes de modelos. Cada modelo pode ser usado para lidar com cenários diferentes.
Selecione Criar.
Depois que o modelo for implantado, selecione Conclusões na seção Playground .
Selecione o modelo gpt-35-turbo na lista suspensa Implantações . Selecione Gerar um email na lista suspensa Exemplos .
Reserve um momento para ler o texto do prompt fornecido. Selecione Gerar para ver o texto gerado pelo modelo.
Aviso
Se você receber uma mensagem de erro sobre o modelo não estar pronto, aguarde alguns minutos e tente novamente. Pode levar alguns minutos para que o modelo seja totalmente implantado e pronto para ser usado.
Se você receber um erro dizendo: "A operação de conclusão não funciona com o modelo especificado.", isso normalmente significa que você selecionou uma versão de modelo mais recente em vez da versão padrão. Selecione Implantações e exclua o modelo criado anteriormente. Crie uma implantação de modelo gpt-35-turbo , selecione Atualização automática como padrão para a versão modelo, dê a ele um nome de gpt-35-turbo e aguarde até que o modelo seja totalmente implantado. Depois de implantado, volte para o Playground e tente concluir novamente.
Selecione Regenerar várias vezes. Observe que o texto é diferente a cada vez.
À direita da tela, você verá propriedades listadas, como Temperatura. Altere o valor Temperatura para 0 e selecione Regenerar novamente. Leia o texto de email gerado.
Selecione Regenerar uma última vez e observe que o texto de email é o mesmo que o texto que foi gerado anteriormente.
Observação
Reduzir a temperatura significa que o modelo produzirá respostas mais repetitivas e determinísticas. O aumento da temperatura resultará em respostas mais inesperadas ou criativas.
Atualizar o arquivo do .env
projeto
Voltar para 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 *Ponto de extremidade 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 de
OPENAI_MODEL
eOPENAI_API_VERSION
já estão definidos no arquivo .env . O valor do modelo é definido como gpt-35-turbo , que deve corresponder ao nome 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 .
Iniciar os Serviços de Aplicativos
É hora de iniciar seus serviços de aplicativo, 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 Visual Studio Code e selecione Abrir no Terminal Integrado. Verifique se o terminal está 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 podman-compose instalado e em execução, execute
podman-compose up
na janela do terminal e pressione Enter.Para executar o contêiner postgreSQL diretamente usando Docker Desktop, Podman, nerdctl ou outro runtime de contêiner instalado, execute o seguinte comando na janela do terminal:
Mac, Linux ou Subsistema do 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 de banco de dados for iniciado, pressione o + ícone na barra de ferramentas Visual Studio Code Terminal 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 Visual Studio Code Terminal 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á levado para http://localhost:4200.
IA: Linguagem natural para SQL
A citação "Só porque você não pode significa que você deve" é um guia útil ao pensar sobre os recursos de IA. Por exemplo, o recurso de linguagem natural para SQL do Azure OpenAI permite que os usuários façam consultas de 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 enquanto também discute considerações importantes para ter em mente 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 sintaxe SQL intrincada ou depender 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 a linguagem natural para o SQL funciona, apresentar algumas considerações importantes, fazer você pensar em prós e contras e mostrar o código para começar.
Neste exercício, você vai:
- Use prompts de GPT para converter a linguagem natural em SQL.
- Experimente diferentes prompts de 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 de GPT que podem ser usados para converter a linguagem natural em SQL.
Usando a linguagem natural para o recurso 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.Voltar para o navegador (http://localhost:4200) e localize a seção Consulta Personalizada da página abaixo da datagrid. Observe que um valor de consulta de exemplo já está incluído: obtenha a receita total de todos os pedidos. Agrupar por empresa e incluir a cidade.
Selecione o botão Executar Consulta . Isso passará a consulta de linguagem natural do usuário para o OpenAI do Azure, que a converterá em SQL. Em seguida, a consulta SQL será usada para consultar o banco de dados e retornar quaisquer resultados potenciais.
Execute a seguinte Consulta Personalizada:
Get the total revenue for Adventure Works Cycles. Include the contact information as well.
Exiba a janela do 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"] }
Voltar para o navegador e selecione Redefinir Dados para exibir todos os clientes novamente no datagrid.
Explorando a linguagem natural para o código SQL
Dica
Se você estiver usando Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que você deseja abrir.
Observação
O objetivo deste exercício é mostrar o que é possível com a linguagem natural para a funcionalidade do SQL e demonstrar como começar a usá-lo. Conforme 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 a linguagem natural para o recurso SQL em ação, vamos examinar como ela é implementada.
Abra o arquivo de 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 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 usuário de
req.body.query
e o atribui a uma variável chamadauserQuery
. Esse valor será usado no prompt gpt. - Ele chama uma
getSQLFromNLP()
função para converter a 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 usuário de
Abra o arquivo de servidor/openAI.ts no editor e localize a
getSQLFromNLP()
função. Essa função é chamada pelageneratesql
rota e é usada para converter a 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 only 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. - Always return a JSON object with the SQL query and the parameter values in it. - Return a JSON object. Do NOT include any text outside of the JSON object. - Example JSON object to return: { "sql": "", "paramValues": [] } 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"] } - Convert any strings to a PostgreSQL parameterized query value to avoid SQL injection attacks. - Do NOT include any text outside of the JSON object. Do not provide any additional explanations or context. Just the JSON object is needed. `; 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. - Um
systemPrompt
define o tipo de IA assistente 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 e os parâmetros do SQL 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 forem encontrados valores proibidos, a consulta SQL será definida como uma cadeia de caracteres vazia.
- Um
Vamos percorrer o prompt do sistema com mais detalhes:
const systemPrompt = ` Assistant is a natural language to SQL bot that returns only 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. - Always return a JSON object with the SQL query and the parameter values in it. - Return a JSON object. Do NOT include any text outside of the JSON object. - Example JSON object to return: { "sql": "", "paramValues": [] } 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"] } - Convert any strings to a PostgreSQL parameterized query value to avoid SQL injection attacks. - Do NOT include any text outside of the JSON object. Do not provide any additional explanations or context. Just the JSON object is needed. `;
O tipo de IA assistente a ser usado é definido. Nesse caso, uma "linguagem natural para o bot SQL".
Nomes de tabela e 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 contêm apenas os dados que os usuários têm permissão para consultar usando a linguagem natural para SQL.
Uma regra é definida para converter 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 (e nada mais) com a consulta SQL e os valores de parâmetro nele.
Um exemplo é fornecido para o tipo de objeto JSON a ser retornado.
Exemplos de prompts de usuário e os valores de parâmetro e consulta SQL esperados são fornecidos. Isso é chamado de aprendizado "poucos tiros". Embora as LLMs sejam treinadas em grandes quantidades de dados, elas podem ser adaptadas 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 de parâmetro e consulta SQL corretos.
Duas regras críticas são repetidas novamente na parte inferior do prompt do sistema para evitar "viés de recência".
Dica
Saiba mais sobre o viés de relevância na documentação do Azure OpenAI.
A
getSQLFromNLP()
função envia o sistema e os prompts do usuário para uma função chamadacallOpenAI()
que também está localizada no arquivo de servidor/openAI.ts . AcallOpenAI()
função determina se o serviço OpenAI do Azure ou o serviço OpenAI devem ser chamados verificando 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, OpenAI será chamado.function callOpenAI(systemPrompt: string, userPrompt: string, temperature = 0, useBYOD = false) { const isAzureOpenAI = OPENAI_API_KEY && OPENAI_ENDPOINT && OPENAI_MODEL; if (isAzureOpenAI && useBYOD) { return getAzureOpenAIBYODCompletion(systemPrompt, userPrompt, temperature); } if (isAzureOpenAI) { 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á OpenAI. Se você optar por usar o OpenAI em vez do OpenAI do Azure, poderá ver resultados diferentes em alguns casos.Localize a
getAzureOpenAICompletion()
função.async function getAzureOpenAICompletion(systemPrompt: string, userPrompt: string, temperature: number): Promise<string> { checkRequiredEnvVars(['OPENAI_API_KEY', 'OPENAI_ENDPOINT', 'OPENAI_MODEL']); const fetchUrl = `${OPENAI_ENDPOINT}/openai/deployments/${OPENAI_MODEL}/chat/completions?api-version=${OPENAI_API_VERSION}`; const messageData: ChatGPTData = { max_tokens: 1024, temperature, messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt } ] }; const headersBody: OpenAIHeadersBody = { method: 'POST', headers: { 'Content-Type': 'application/json', 'api-key': OPENAI_API_KEY }, body: JSON.stringify(messageData), }; const completion = await fetchAndParse(fetchUrl, headersBody); console.log(completion); let content = (completion.choices[0]?.message?.content?.trim() ?? '') as string; console.log('Azure OpenAI Output: \n', content); if (content && content.includes('{') && content.includes('}')) { content = extractJson(content); } console.log('After parse: \n', content); return content; } function checkRequiredEnvVars(requiredEnvVars: string[]) { for (const envVar of requiredEnvVars) { if (!process.env[envVar]) { throw new Error(`Missing ${envVar} in environment variables.`); } } } async function fetchAndParse(url: string, headersBody: Record<string, any>): Promise<any> { try { const response = await fetch(url, headersBody); return await response.json(); } catch (error) { console.error(`Error fetching data from ${url}:`, error); throw error; } }
Essa função faz o seguinte:
Aceita os parâmetros
systemPrompt
,userPrompt
etemperature
.-
systemPrompt
: permite que o modelo openai do Azure saiba qual função ele deve desempenhar e quais regras seguir. -
userPrompt
: informações do usuário inseridas no aplicativo, como linguagem natural ou regras que serão usadas pelo modelo para gerar a saída. -
temperature
: determina o quão criativo o modelo deve ser ao gerar uma resposta. Um valor mais alto significa que o modelo correrá mais riscos.
-
Garante que uma chave, um ponto de extremidade e um modelo válidos da API OpenAI do Azure estejam disponíveis chamando
checkRequiredEnvVars()
.Cria um
fetchUrl
valor usado para chamar a API REST do Azure OpenAI e insira os valores de versão de ponto de extremidade, modelo e API das variáveis de ambiente na URL.Cria um
messageData
objeto que incluimax_token
,temperature
emessages
para enviar para o Azure OpenAI.-
max_tokens
: o número máximo de tokens a serem gerados na conclusão. A contagem de tokens da sua solicitação mais max_tokens não pode exceder o tamanho do contexto do modelo. Os modelos mais antigos têm um comprimento de contexto de 2.048 tokens, enquanto os mais recentes dão suporte a 4.096, 8.192 ou até mesmo 32.768 tokens, dependendo do modelo que está sendo usado. -
temperature
: qual temperatura de amostragem usar. Um valor mais alto significa que o modelo correrá mais riscos. Experimente 0.9 para aplicativos mais criativos e 0 para os que tiverem uma resposta bem definida. -
messages
: representa as mensagens para as quais gerar conclusões de chat, no formato de chat. Neste exemplo, duas mensagens são passadas: uma para o sistema e outra para o usuário. A mensagem do sistema define o comportamento geral e as regras que serão usadas, enquanto a mensagem do usuário define o texto do prompt fornecido pelo usuário.
-
Chama
fetchAndParse()
para enviar os valores eheadersBody
para ofetchUrl
OpenAI do Azure.Processa a resposta recuperando o
completion.choices[0].message.content
valor. Se a resposta contiver os resultados esperados, o código extrairá o objeto JSON da resposta e o retornará.Observação
Você pode saber mais sobre esses parâmetros e outras pessoas na documentação de referência do Azure OpenAI.
Comente as seguintes linhas na
getSQLFromNLP()
função:// if (isProhibitedQuery(queryData.sql)) { // queryData.sql = ''; // }
Salve openAI.ts. O servidor de API recriará automaticamente o código TypeScript e reiniciará o servidor.
Voltar para o navegador e insira Selecionar todos os nomes de tabela do banco de dados na entrada Consulta Personalizada. Selecione Executar Consulta. Os nomes de tabela são exibidos?
Voltar à
getSQLFromNLP()
função no servidor/openAI.ts e adicione a regra a seguir àRules:
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.
Voltar para o navegador e execute as seguintes tarefas:
- Insira Selecionar todos os nomes de tabela do banco de dados na entrada Consulta Personalizada . Selecione Executar Consulta. Os nomes de tabela 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 de função são exibidos?
PERGUNTA: Por que isso ainda está funcionando depois de adicionar uma regra informando que nomes de tabela, nomes de função e nomes de procedimento não são permitidos?
RESPOSTA: isso ocorre devido à regra "somente JSON". Se as regras forem mais flexíveis e não exigirem que um objeto JSON seja retornado, você poderá ver uma mensagem sobre o OpenAI do Azure não conseguir executar a tarefa.
Observação
É importante observar que os modelos OpenAI podem retornar resultados inesperados em algumas ocasiões que podem não corresponder às regras definidas. É importante planejar isso em seu código.
Tire a regra a seguir de
systemPrompt
e salve o arquivo.- Only return a JSON object. Do NOT include any text outside of the JSON object. Do not provide any additional explanations or context. Just the JSON object is needed.
Execute Selecionar todos os nomes de tabela na consulta de banco de dados novamente.
Observe que a mensagem agora é exibida no navegador. O OpenAI do Azure não consegue executar a tarefa devido à regra a seguir. Como removemos a regra "somente JSON", a resposta pode fornecer detalhes adicionais sobre por que a tarefa não pode ser executada.
- Do not allow the SELECT query to return table names, function names, or procedure names.
Você pode ver que a IA pode gerar resultados inesperados mesmo se você tiver regras específicas em vigor. É por isso que você precisa planejar cuidadosamente o texto do prompt e as regras, mas também planeja adicionar uma etapa pós-processamento ao seu código para lidar com casos em que você recebe resultados inesperados.
Voltar para servidor/openAI.ts e localize a
isProhibitedQuery()
função. Este é um exemplo de código pós-processamento que pode ser executado após o Azure OpenAI retornar resultados. Observe que ela 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_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 esse é apenas o 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 a 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á considerar a segurança.
Voltar para servidor/openAI.ts e descompacte o código a
getSQLFromNLP()
seguir na função. Salve o arquivo.if (isProhibitedQuery(queryData.sql)) { queryData.sql = ''; }
Remova a regra a seguir de
systemPrompt
e salve o arquivo.- Do not allow the SELECT query to return table names, function names, or procedure names.
Voltar 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 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:
Simpatia do usuário: esse recurso pode tornar a interação do banco de dados mais acessível aos usuários sem experiência técnica, reduzindo a necessidade de conhecimento do SQL e potencialmente acelerando as operações.
Aumento da 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 contar com especialistas técnicos, aumentando assim a eficiência.
Aplicativo amplo: 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 puderem interagir com bancos de dados usando linguagem natural, será necessário haver medidas de segurança robustas para impedir o acesso não autorizado ou consultas mal-intencionadas. Você pode considerar a implementação de um modo somente leitura para impedir que os usuários modifiquem dados.
Privacidade de dados: determinados 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 de usuário estejam em vigor.
Precisão: embora o processamento de linguagem natural tenha melhorado significativamente, ele não é perfeito. A interpretação incorreta de consultas de 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 poderão ser necessárias se as regras 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ê não pode significa que você deve" se aplica aqui. Tenha extrema cautela e planejamento cuidadoso antes de integrar a linguagem natural ao SQL em um aplicativo. É importante entender os riscos potenciais e 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, stakeholders e quaisquer outras partes relevantes para garantir que ela seja apropriada para sua organização. É importante discutir se a linguagem natural para SQL atende à segurança, à privacidade e a quaisquer outros requisitos que sua organização possa ter em vigor.
- 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 entrar nela para garantir que os prompts tenham regras necessárias e que a funcionalidade pós-processamento seja incluída. Planeje um tempo adicional para implementar e testar esse tipo de funcionalidade e considerar 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 OpenAI do Azure para converter a linguagem natural em SQL e aprendeu sobre os prós e contras da implementação desse tipo de funcionalidade. No próximo exercício, você aprenderá como emails e mensagens SMS podem ser gerados usando o OpenAI do Azure.
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 melhorar 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 "A ordem atrasou 5 dias" e o sistema gerará automaticamente mensagens sms e email contextualmente apropriadas com base nessas regras.
Essa funcionalidade serve como um "jump start" para os usuários, fornecendo a eles um modelo de mensagem cuidadosamente criado que eles podem personalizar facilmente antes de enviar. O resultado é uma redução significativa no tempo e no 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 só 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 de GPT.
- Use prompts gpt para gerar conclusões para emails e mensagens SMS.
- Explore o código que habilita as conclusões de GPT.
- Saiba mais sobre a importância da engenharia de prompts e da inclusão de regras em seus prompts.
Vamos começar experimentando regras diferentes que podem ser usadas para gerar emails e mensagens SMS.
Usando o recurso de conclusão de GPT
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.Voltar para o navegador (http://localhost:4200) e selecione Contatar Cliente em qualquer linha no datagrid seguido por Email/Cliente SMS para acessar a tela Gerador de Mensagens.
Isso usa o OpenAI do Azure para converter regras de mensagem definidas em mensagens Email/SMS. Execute as seguintes tarefas:
Insira uma regra como Ordem atrasada 5 dias na entrada e selecione o botão Gerar mensagens Email/SMS.
Você verá um assunto e um corpo gerados para o email e uma mensagem curta gerada para o SMS.
Observação
Como Serviços de Comunicação do Azure ainda não está habilitado, você não poderá enviar o email ou mensagens SMS.
Feche a janela de diálogo email/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 GPT
Dica
Se você estiver usando Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que você deseja abrir.
Abra o arquivo de servidor/apiRoutes.ts e localize a
completeEmailSmsMessages
rota. Essa API é chamada por parte de front-end do aplicativo quando o botão Gerar mensagens Email/SMS é selecionado. Ele recupera os valores de prompt do usuário, da empresa e do nome de contato do corpo e os passa para acompleteEmailSMSMessages()
função no arquivo de servidor/openAI.ts . Em seguida, os resultados sã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 de servidor/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. - Only return a valid JSON object. Do NOT include any text outside of the JSON object. Do not provide any additional explanations or context. Just the JSON object is needed. `; 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; }
Essa função tem os seguintes recursos:
-
systemPrompt
é usado para definir que uma IA assistente capaz de gerar emails e mensagens SMS é necessária. OsystemPrompt
também inclui:- As regras para o assistente seguir 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 nesse caso e apenas um objeto JSON.
- Duas regras críticas são repetidas novamente na parte inferior do prompt do sistema para evitar "viés de recência".
-
userPrompt
é usado para definir as regras e o nome de contato que o usuário final gostaria de incluir à medida que as mensagens sms e email são geradas. A regra Ordem está atrasada 5 dias que você inseriu anteriormente está incluída emuserPrompt
. - A função chama a
callOpenAI()
função que você explorou anteriormente para gerar o email e as conclusões de SMS.
-
Voltar para o navegador, atualize a página e selecione Contatar Cliente em qualquer linha seguida por Email/Cliente SMS para acessar a tela Gerador de Mensagens novamente.
Insira as seguintes regras na entrada gerador de mensagens:
- O pedido está adiantado.
- Diga ao cliente para nunca mais pedir de nós, não queremos seus negócios.
Selecione Gerar mensagens Email/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.Voltar para servidor/openAI.ts* no 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.Voltar para o gerador de mensagens sms/email no navegador e execute as mesmas regras novamente:
- O pedido está adiantado.
- Diga ao cliente para nunca mais pedir de nós, não queremos seus negócios.
Selecione Gerar mensagens Email/SMS e observe a mensagem retornada.
O que está acontecendo nesses cenários? Ao usar o OpenAI do Azure, a filtragem de conteúdo é 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 da engenharia de seus prompts com as informações e regras certas para garantir que os resultados adequados sejam retornados. Leia mais sobre esse processo na documentação Introdução à engenharia de prompt .
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ê deverá ver o email e as mensagens SMS retornados 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 examinar as mensagens geradas. Neste exemplo, as conclusões do OpenAI do Azure retornam mensagens sms e email sugeridas, mas o usuário pode substituí-las antes de serem enviadas. Se você planeja automatizar emails, é importante ter algum tipo de processo de revisão humana para garantir que as mensagens aprovadas sejam enviadas. Veja a IA como sendo um copilot, 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. Convide outros stakeholders do projeto para revisar as conclusões também.
- Talvez seja necessário incluir o código pós-processamento para garantir que os 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: Traga seus próprios dados
A integração do NLP (Processamento de Linguagem Natural) do Azure OpenAI e dos recursos de conclusão oferece um potencial significativo para aumentar a produtividade do usuário. Aproveitando as solicitações e regras apropriadas, um assistente de IA pode gerar com eficiência várias formas de comunicação, como mensagens de email, mensagens SMS e muito mais. Essa funcionalidade leva a maior eficiência do usuário e fluxos de trabalho simplificados.
Embora esse recurso seja bastante poderoso por conta própria, pode haver casos em que os usuários precisam 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 desafiadores para os usuários navegarem quando estiverem auxiliando os clientes com problemas de instalação. Como alternativa, você pode manter um conjunto abrangente de perguntas frequentes relacionadas aos benefícios de saúde que podem ser desafiadores para os usuários lerem e obterem as respostas necessárias. 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 Azure OpenAI.
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. O OpenAI do Azure com seus dados, junto com o Azure Cognitive Search, 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 Estúdio de IA do Azure.
- Implante um modelo de inserção usando Estúdio de IA do Azure.
- Carregar documentos personalizados.
- Inicie uma sessão de chat no chat playground para experimentar a geração de conclusões com base em seus próprios dados.
- Explore o código que usa Azure Cognitive Search e o OpenAI do Azure 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 em Estúdio de IA do Azure.
Adicionando uma fonte de dados personalizada a Estúdio de IA do Azure
Navegue até o Azure OpenAI Studio e entre com credenciais que tenham acesso ao recurso openAI do Azure.
Selecione Implantações no menu de navegação.
Selecione Criar nova implantação e insira os seguintes valores:
- Modelo: text-embedding-ada-002.
- Versão do modelo: padrão.
- Nome da implantação: text-embedding-ada-002.
Depois que o modelo for criado, selecione OpenAI do Azure 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 Experimentar agora.
Selecione Carregar arquivos na lista suspensa Selecionar fonte de dados .
Na lista suspensa Selecionar recurso de Armazenamento de Blobs do Azure , selecione Criar um recurso de Armazenamento de Blobs do Azure.
Isso levará você ao portal do Azure em que 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 Examinar seguido por Criar.
Depois que o recurso de armazenamento de blobs for criado, volte para a caixa de diálogo Estúdio de IA do Azure e selecione o recurso de armazenamento de blobs recém-criado na lista suspensa Selecionar recurso do 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 Estúdio de IA do Azure.
Na lista suspensa Selecionar Azure Cognitive Search recurso, selecione Criar um recurso de Azure Cognitive Search.
Isso o levará de volta à portal do Azure em que você pode executar as seguintes tarefas:
- Insira um nome exclusivo para o recurso do Cognitive Search, como byodsearch[Seu Sobrenome].
- 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 por Selecionar. Não há suporte para a camada gratuita, portanto, você limpo o recurso do Cognitive Search no final deste tutorial.
- Selecione Examinar seguido por Criar.
Depois que o recurso do Cognitive Search for criado, vá para a página Visão geral do recurso e copie o valor da URL para um arquivo local.
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á desses valores posteriormente no exercício.
Selecione Classificador semântico no menu de navegação à esquerda e verifique se Gratuito está selecionado.
Observação
Para marcar se o classificador semântico estiver 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.
Voltar à caixa de diálogo Adicionar Dados Estúdio de IA do Azure e selecione o recurso de pesquisa recém-criado na lista suspensa Selecionar recurso Azure Cognitive 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 Inserir o nome do índice .
Marque a caixa de seleção Adicionar pesquisa de vetor a este recurso de pesquisa .
Na lista suspensa Selecionar um modelo de inserção , selecione o modelo text-embedding-ada-002 criado anteriormente.
Marque a caixa de seleção seguida por Avançar.
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:
- Instructions.docxde instalação do Relógio A102
- FAQs.docxda empresa
Observação
Atualmente, esse recurso dá 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 criado 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 palavra-chave e pesquisa de vetor. Depois que os resultados são retornados, um processo de classificação secundária é 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, veja a pesquisa semântica na documentação do Azure Cognitive Search.
Marque as caixas de seleção para confirmar os custos associados ao uso de inserções de vetor e pesquisa semântica.
Selecione Avançar, examine os detalhes e selecione Salvar e fechar.
Agora que seus dados personalizados foram carregados, os dados serão indexados e estarão disponíveis para uso no Playground de chat. Esse processo pode levar alguns minutos. Depois de concluído, prossiga para a próxima seção.
Usando sua fonte de dados personalizada no Chat Playground
Localize a seção Sessão de chat da página em Estúdio de IA do Azure e insira a seguinte mensagem de usuário:
What safety rules are required to install a clock?
Você deverá ver um resultado semelhante ao seguinte exibido:
Expanda a seção 1 referências na resposta de chat e observe que o arquivo Instructions.docxde Instalação do Relógio A102 está listado e que você pode selecioná-lo para exibir o documento.
Insira 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 perguntas frequentes sobre a empresa. Insira o seguinte texto no campo Mensagem 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 Mensagem 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.docxda Empresa está listado e que você pode selecioná-lo para exibir o documento.
Selecione Exibir código na parte superior da seção Sessão de chat .
Observe que você pode alternar entre idiomas diferentes, exibir o ponto de extremidade e acessar a chave do ponto de extremidade. Feche a janela da caixa de diálogo Código de Exemplo .
Ative a alternância Mostrar JSON bruto na sessão *Chat. 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 experimentou-a 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
Voltar ao projeto no Visual Studio Code e abra o arquivo .env. Atualize os valores a seguir com o ponto de extremidade, a chave e o nome do índice dos Serviços Cognitivos. Você copiou o ponto de extremidade e a chave para um arquivo local anteriormente neste exercício.
AZURE_COGNITIVE_SEARCH_ENDPOINT=<COGNITIVE_SERVICES_ENDPOINT_VALUE> AZURE_COGNITIVE_SEARCH_KEY=<COGNITIVE_SERVICES_KEY_VALUE> AZURE_COGNITIVE_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 tiver sido carregado no navegador, selecione o ícone Ajuda de Chat no canto superior direito do aplicativo.
O texto a seguir deve aparecer na caixa de diálogo de chat:
How should I handle refund requests?
Selecione o botão Obter Ajuda . Você deverá ver os resultados retornados do documento FAQs.docxda Empresa que você carregou anteriormente no Estúdio de IA do Azure. 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ê deverá ver os resultados retornados do documento Instructions.docxde Instalação do Relógio A102 que você carregou anteriormente no Estúdio de IA do Azure. 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 Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que você deseja abrir.
Voltar ao código-fonte do projeto em Visual Studio Code.
Abra o arquivo de servidor/apiRoutes.ts e localize a
completeBYOD
rota. Essa API é chamada quando o botão Obter Ajuda é selecionado na caixa de diálogo Ajuda de Chat. Ele recupera o prompt do usuário do corpo da solicitação e o passa para acompleteBYOD()
função no arquivo de servidor/openAI.ts . Em seguida, os resultados sã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 de servidor/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.'; // Pass that we're using Cognitive Search along with Azure OpenAI. return await callOpenAI(systemPrompt, userPrompt, 0, true); }
Essa função tem os seguintes recursos:
- O
userPrompt
parâmetro contém as informações que o usuário digitou na caixa de diálogo de ajuda de chat. - a
systemPrompt
variável define que um assistente de IA projetado para ajudar as pessoas a encontrar informações será usado. -
callOpenAI()
é usado para chamar a API 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 para que o valor seja definido como 0. -
useBYOD
- Um valor booliano que indica se o Cognitive Search deve ou não ser usado junto com o OpenAI do Azure. Nesse caso, ele é definido como para que atrue
funcionalidade do Cognitive Search seja usada.
-
- O
A
callOpenAI()
função aceita umuseBYOD
parâmetro usado para determinar qual função OpenAI chamar. Nesse caso, ele defineuseBYOD
como paratrue
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 && useBYOD) { // Azure OpenAI + Cognitive Search: Bring Your Own Data return getAzureOpenAIBYODCompletion(systemPrompt, userPrompt, temperature); } if (isAzureOpenAI) { // Azure OpenAI return getAzureOpenAICompletion(systemPrompt, userPrompt, temperature); } // OpenAI return getOpenAICompletion(systemPrompt, userPrompt, temperature); }
Localize a
getAzureOpenAIBYODCompletion()
função no servidor/openAI.ts. Ele é bastante semelhante àgetAzureOpenAICompletion()
função que você examinou anteriormente, mas é mostrado como uma função separada para destacar algumas diferenças importantes que são exclusivas para o cenário "traga seus próprios dados" disponível no OpenAI do Azure.O
fetchUrl
valor inclui umextensions
segmento na URL, enquanto a URL da API padrão do Azure OpenAI não.const fetchUrl = `${OPENAI_ENDPOINT}/openai/deployments/${OPENAI_MODEL}/extensions/chat/completions?api-version=${OPENAI_API_VERSION}`;
Uma
dataSources
propriedade é adicionada ao objeto enviado ao OpenAI domessageData
Azure. AdataSources
propriedade contém os valores ,key
eindexName
doendpoint
recurso cognitive search que foram adicionados ao.env
arquivo anteriormente neste exercício.const messageData: ChatGPTData = { max_tokens: 1024, temperature, messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt } ], // Adding BYOD data source so that Cognitive Search is used with Azure OpenAI dataSources: [ { type: 'AzureCognitiveSearch', parameters: { endpoint: AZURE_COGNITIVE_SEARCH_ENDPOINT, key: AZURE_COGNITIVE_SEARCH_KEY, indexName: AZURE_COGNITIVE_SEARCH_INDEX } } ] };
O
headersBody
objeto incluichatpgpt_url
propriedades echatgpt_key
que são usadas para chamar o Azure OpenAI depois que os resultados da Pesquisa Cognitiva são obtidos.const headersBody: OpenAIHeadersBody = { method: 'POST', headers: { 'Content-Type': 'application/json', 'api-key': OPENAI_API_KEY, chatgpt_url: fetchUrl.replace('extensions/', ''), chatgpt_key: OPENAI_API_KEY }, body: JSON.stringify(messageData), };
A resposta retornada pelo OpenAI do Azure inclui dois problemas com funções de
tool
eassistant
. O aplicativo de exemplo usa a segunda mensagem com umrole
deassistant
para fornecer ao usuário as informações solicitadas. Nos casos em que você deseja fornecer informações adicionais sobre os documentos usados para criar a resposta (como você viu anteriormente no playground do Estúdio de IA do Azure), você pode usar a primeira mensagem que inclui ourl
para os documentos.{ "id": "12345678-1a2b-3c4e5f-a123-12345678abcd", "model": "", "created": 1684304924, "object": "chat.completion", "choices": [ { "index": 0, "messages": [ { "role": "tool", "content": "{\"citations\": [{\"content\": \"\\nCognitive Services are cloud-based artificial intelligence (AI) services...\", \"id\": null, \"title\": \"What is Cognitive Services\", \"filepath\": null, \"url\": null, \"metadata\": {\"chunking\": \"orignal document size=250. Scores=0.4314117431640625 and 1.72564697265625.Org Highlight count=4.\"}, \"chunk_id\": \"0\"}], \"intent\": \"[\\\"Learn about Azure Cognitive Services.\\\"]\"}", "end_turn": false }, { "role": "assistant", "content": " \nAzure Cognitive Services are cloud-based artificial intelligence (AI) services that help developers build cognitive intelligence into applications without having direct AI or data science skills or knowledge. [doc1]. Azure Machine Learning is a cloud service for accelerating and managing the machine learning project lifecycle. [doc1].", "end_turn": true } ] } ] }
O código a seguir é usado no
getAzureOpenAIBYODCompletion()
para acessar as mensagens. Embora as citações não estejam sendo usadas neste exemplo, elas são registradas no console para que você possa ver o tipo de dados retornado.const completion = await fetchAndParse(fetchUrl, headersBody); console.log(completion); if (completion.error) { console.error('Azure OpenAI BYOD Error: \n', completion.error); return completion.error.message; } const citations = (completion.choices[0]?.messages[0]?.content?.trim() ?? '') as string; console.log('Azure OpenAI BYOD Citations: \n', citations); let content = (completion.choices[0]?.messages[1]?.content?.trim() ?? '') as string; console.log('Azure OpenAI BYOD Output: \n', content); return content;
Alguns pontos finais a serem considerados antes de passar para o próximo exercício:
- O recurso "traga seus próprios dados" do Azure OpenAI está atualmente em versão prévia. Não é recomendável usá-lo em aplicativos de produção no momento.
- O aplicativo de exemplo usa um único índice em Azure Cognitive Search. Você pode usar vários índices e fontes de dados com o Azure OpenAI. A
dataSources
propriedade nagetAzureOpenAIBYODCompletion()
função pode ser atualizada para incluir várias fontes de dados 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 eles não podem acessar.
Agora que você aprendeu sobre o Azure OpenAI, prompts, conclusões e como você pode usar seus próprios dados, vamos passar 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 OpenAI do Azure, exiba 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 no OpenAI do Azure na documentação de dados .
Comunicação: criando um recurso de Serviços de Comunicação do Azure
A comunicação efetiva é essencial para aplicativos de negócios personalizados bem-sucedidos. Usando 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 sms e email. Agora, você aprenderá a 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 acs (Serviços de Comunicação do Azure).
- Adicione um número de telefone gratuito com recursos de chamada e SMS.
- Conectar um domínio de email.
- Atualize o arquivo .env do projeto com valores do recurso ACS.
Criar um recurso de Serviços de Comunicação do Azure
Visite o portal do Azure no navegador e entre se ainda não tiver 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 caso não exista).
- Insira um nome de recurso do ACS. Ele precisa ser um valor exclusivo.
- Selecione um local de dados.
Selecione Examinar + Criar seguido por Criar.
Você criou com êxito um novo recurso de Serviços de Comunicação do Azure! Em seguida, você habilitará as funcionalidades de chamada telefônica e SMS. Você também conectará um domínio de email ao recurso.
Habilitar chamadas telefônicas e recursos de 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 do aplicativo.
Selecione
Phone numbers
no menu Recurso.Selecione
+ Get
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
-
Caso de uso: selecione
An application will be making calls or sending SMS mesages
- Tipo de número: chamada gratuita
Observação
Um cartão de crédito é necessário em sua assinatura do Azure para criar o número de chamada gratuita. Se você não tiver um cartão no arquivo, fique à vontade para ignorar a adição de um número de telefone e ir para a próxima seção do exercício que conecta um domínio de email. Você ainda pode usar o aplicativo, mas não poderá ligar para um número de telefone.
-
Chamando:
Make calls
-
SMS:
Send and receive SMS
-
País ou região:
Selecione Avançar: Números.
Selecione um Prefixo (por exemplo
877
) e deixe a Quantidade em 1. Selecione Pesquisar.Depois que um número de chamada gratuita for exibido, selecione Avançar: Resumo.
Examine os detalhes e selecione Fazer pedido para adicionar o número de telefone ao recurso do ACS.
Depois que o número de telefone for criado, selecione-o para acessar o painel Recursos . Verifique se os seguintes valores estão definidos:
- Na seção Chamada , selecione
Make calls
. - Na seção SMS , selecione
Send and receive SMS
. - Clique em Salvar.
- Na seção Chamada , selecione
Copie o valor do número de telefone em um arquivo para uso posterior.
Conectar um domínio Email
Execute as tarefas a seguir para criar um domínio de email conectado para o recurso ACS para que você possa enviar emails. Isso será usado para enviar emails do aplicativo.
- Selecione Domínios no menu Recurso.
- Selecione Conectar domínio na barra de ferramentas.
- Selecione sua Assinatura e Grupo de recursos.
- Na lista suspensa Serviço Email, selecione
Add an email service
. - Dê um nome ao serviço de email, como
acs-demo-email-service
. - Selecione
Review + create
seguido porCreate
. - 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 EmailDo endereços no menu Recurso.
- Copie o valor MailFrom para um arquivo. Você o usará mais tarde à medida que atualizar o arquivo .env .
- Voltar ao recurso Serviços de Comunicação do Azure e selecione
Domains
no menu Recurso. - Selecione
Add domain
e insira oMailFrom
valor da etapa anterior (verifique se você selecionou a assinatura, o grupo de recursos e o serviço de email corretos). Selecione o botãoConnect
.
Atualizar o .env
arquivo
Agora que o número de telefone do ACS (com chamada e SMS habilitado) 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 seu valor de endereço de email "MailTo".CUSTOMER_EMAIL_ADDRESS
: atribua um endereço de email para o qual você gostaria que o email fosse enviado do aplicativo (já que os dados do cliente no banco de dados do aplicativo são apenas dados de exemplo). Você pode usar um endereço de email pessoal.CUSTOMER_PHONE_NUMBER
: você precisará fornecer um número de telefone baseado em Estados Unidos (a partir de hoje) devido à verificação adicional necessária em outros países para enviar mensagens SMS. Se você não tiver um número baseado nos EUA, poderá deixá-lo vazio.
Iniciar/reiniciar o aplicativo e os servidores de API
Execute uma das seguintes etapas com base nos exercícios que você concluiu 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 de 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 interrompê-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 Visual Studio Code e selecione Abrir no Terminal Integrado. Verifique se o terminal está 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 podman-compose instalado e em execução, execute
podman-compose up
na janela do terminal e pressione Enter.Para executar o contêiner postgreSQL diretamente usando Docker Desktop, Podman, nerdctl ou outro runtime de contêiner que você instalou, execute o seguinte comando na janela do terminal:
Mac, Linux ou Subsistema do 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 de banco de dados for iniciado, pressione o + ícone na barra de ferramentas do Terminal 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 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á levado para http://localhost:4200.
Comunicação: fazendo uma chamada telefônica
A integração dos recursos de chamada telefônica da 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 rápida resolução 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 valores a seguir 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>
Verifique se você concluiu o exercício anterior antes de continuar.
Voltar para o navegador (http://localhost:4200), localize o datagrid e selecione Contatar Cliente seguido por Cliente de Chamada na primeira linha.
Um componente de chamada telefônica será adicionado ao cabeçalho . Insira seu número de telefone (verifique se ele começa com + e inclui o código do país) e selecione Chamar. Você será solicitado a permitir o acesso ao 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 Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que você 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 componente de
ngOnInit()
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. Tire 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 principais recursos:
- Recupera um token de acesso 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 termina uma chamada usando as
startCall()
funções eendCall()
, respectivamente.
- Recupera um token de acesso 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 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 de e
AzureCommunicationTokenCredential
usando o token deCallClient
acesso. - Cria uma nova instância de
CallAgent
usando osCallClient
objetos eAzureCommunicationTokenCredential
. Posteriormente, você verá queCallAgent
é usado para iniciar e encerrar uma chamada.
- Cria uma nova instância de 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 a userId e o token de acesso e a 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 = await tokenClient.createUser(); const userToken = await tokenClient.getToken(user, ["voip"]); return { userId: user.communicationUserId, ...userToken }; }
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 vaziouserId
etoken
. - Cria uma nova instância de
CommunicationIdentityClient
e passa oconnectionString
valor para ela. - Cria um novo usuário usando
tokenClient.createUser()
. - Obtém um token para o novo usuário com o escopo "voip" usando
tokenClient.getToken()
. - Retorna um objeto que contém os
userId
valores etoken
.
- Verifica se um valor ACS
Agora que você viu como a userId e o token são recuperados, volte para
phone-call.component.ts
e localize astartCall()
função.Essa função é chamada quando Call é selecionado 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 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; }
A
stopCall()
função é chamada quando Hang Up é 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 do ACS e um token de acesso são recuperados do servidor de API usando a
acsService.getAcsToken()
função . - O token é usado para criar um
CallClient
objeto eCallAgent
. - O
CallAgent
objeto é usado para iniciar e encerrar uma chamada chamando ascallAgent.startCall()
funções ecallAgent.hangUp()
, respectivamente.
- Um userId do ACS e um token de acesso 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 Serviços de Comunicação do Azure para enviar emails e mensagens SMS.
Comunicação: enviando mensagens SMS e Email
Além das chamadas telefônicas, Serviços de Comunicação do Azure também podem enviar emails e mensagens 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 emails e mensagens SMS podem ser enviados do aplicativo.
- Percorra o código para saber como a funcionalidade de email e SMS é implementada.
Usando os recursos de Email e SMS
Em um exercício anterior, você criou um recurso de Serviços de Comunicação do Azure (ACS) 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>
Verifique se você concluiu o exercício antes de continuar.
Voltar para o navegador (http://localhost:4200) e selecione Contatar Cliente seguido por cliente Email/SMS na primeira linha.
Selecione a guia Email/SMS e execute as seguintes tarefas:
- Insira um Email Assunto e Corpo e selecione o botão Enviar Email.
- Insira uma mensagem SMS e selecione o botão Enviar SMS .
Verifique se você recebeu o email e as mensagens SMS. 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 foi capaz de fornecer um número de telefone baseado em Estados Unidos para usar para mensagens SMS, você pode ignorar essa etapa.Observação
Se você não vir a mensagem de email em sua caixa de entrada para o endereço definido para
CUSTOMER_EMAIL_ADDRESS
no arquivo .env, marcar sua pasta de spam.
Explorando o código Email
Dica
Se você estiver usando Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que você 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 Contatar Cliente seguido por cliente Email/SMS na datagrid, 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 do datagrid) contém umaphone
propriedade eemail
. Se isso acontecer, ele criará 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, aacsService.sendEmail()
função será chamada e o assunto do email, o 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 exemplo, 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. - Assina 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 email tiver sido enviado com êxito, a
emailSent
propriedade será 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 lugar.
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 RxJS observável que contém a resposta da chamada à API. - Manipula os erros retornados pela
http.post()
função usando o operador RxJScatchError
.
- Chama a
Agora vamos examinar como o aplicativo interage com o recurso de email 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 o acs cadeia de conexão 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 de 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 email 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 ele foi feito e envia a resposta ao chamador.
Explorando o código SMS
Voltar ao 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 exemplo, 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. - Assina 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 RxJS observável que contém a resposta da chamada à API. - Manipula os erros retornados pela
http.post()
função usando o operador RxJScatchError
.
- Chama a
Por fim, vamos examinar como o aplicativo interage com o recurso DE SMS do ACS. Abra o arquivo acs.ts . O caminho completo para o arquivo é server/typescript/acs.ts e localiza a
sendSms()
função.A
sendSms()
função executa as seguintes tarefas:Cria um novo
SmsClient
objeto e passa o acs cadeia de conexão 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 EMAIL 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 manipula as chamadas à API para o servidor e retorna a resposta ao chamador.
- A API do lado do servidor usa o ACS
EmailClient
eSmsClient
os objetos para enviar emails e mensagens SMS.
Agora que você aprendeu como emails e mensagens SMS podem ser enviados, vamos alternar nosso foco para a integração de dados organizacionais ao aplicativo.
Dados organizacionais: criando um registro de aplicativo Microsoft Entra ID
Aprimore a produtividade do usuário integrando dados organizacionais (emails, arquivos, chats e eventos de calendário) diretamente em seus aplicativos personalizados. Usando APIs e Microsoft Entra ID do Microsoft Graph, você pode recuperar e exibir dados relevantes em seus aplicativos, reduzindo a necessidade de os usuários mudarem de contexto. Seja referenciando um email enviado a um cliente, revisando uma mensagem do Teams ou acessando um arquivo, os usuários podem encontrar rapidamente as informações necessárias sem sair do aplicativo, simplificando o processo de tomada de decisão.
Neste exercício, você vai:
- Crie um Microsoft Entra ID registro de aplicativo para que o Microsoft Graph possa acessar dados organizacionais e trazê-los para o aplicativo.
- Localize
team
echannel
IDs do Microsoft Teams necessárias para enviar mensagens de chat para um canal específico. - Atualize o arquivo .env do projeto com valores do registro do aplicativo Microsoft Entra ID.
Criar um registro de aplicativo Microsoft Entra ID
Vá para portal do Azure e selecione Microsoft Entra ID.
Selecione a guia Registro de aplicativo seguida por + Novo registro.
Preencha os detalhes do novo formulário de registro do 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 Microsoft Entra ID – Multilocatário)
- URI de Redirecionamento:
- Selecione SPA (aplicativo de página única) e insira
http://localhost:4200
no 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 Recurso e copie o
Application (client) ID
valor para sua área de transferência.
Atualizar o arquivo .env do projeto
Abra o arquivo .env no 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.
Depois de entrar, expanda uma equipe e encontre um canal para o qual deseja enviar mensagens do 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
Get link to team
.No link que aparece na janela pop-up, a ID da equipe é a cadeia de caracteres de letras e números após
team/
. Por exemplo, no link "https://teams.microsoft.com/l/team/19%3ae9b9.../", a ID da equipe é 19%3ae9b9... até o caractere a seguir/
.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
Get link to channel
.No link que aparece na janela pop-up, a ID do canal é a cadeia de caracteres de letras e números após
channel/
. Por exemplo, no link "https://teams.microsoft.com/l/channel/19%3aQK02.../", a ID do canal é 19%3aQK02... até o caractere a seguir/
.Copie a ID do canal e atribua-a no
CHANNEL_ID
arquivo .env .Salve o arquivo env antes de continuar.
Iniciar/reiniciar o aplicativo e os servidores de API
Execute uma das seguintes etapas com base nos exercícios que você concluiu até este ponto:
Se você iniciou o banco de dados, o servidor de API e o servidor Web em um exercício anterior, precisará interromper o servidor de API e o servidor Web e reiniciá-los para obter as alterações de 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 interrompê-las. Inicie-os novamente digitando
npm start
em cada janela do terminal e pressionando Enter. Prossiga 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 Visual Studio Code e selecione Abrir no Terminal Integrado. Verifique se o terminal está 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 podman-compose instalado e em execução, execute
podman-compose up
na janela do terminal e pressione Enter.Para executar o contêiner postgreSQL diretamente usando Docker Desktop, Podman, nerdctl ou outro runtime de contêiner instalado, execute o seguinte comando na janela do terminal:
Mac, Linux ou Subsistema do 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 de banco de dados for iniciado, pressione o + ícone na barra de ferramentas Visual Studio Code Terminal 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 Visual Studio Code Terminal 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á levado para http://localhost:4200.
Dados organizacionais: entrar em um usuário e obter um token de acesso
Os usuários precisam se autenticar com Microsoft Entra ID para que o Microsoft Graph acesse dados organizacionais. Neste exercício, você verá como o componente do Kit de Ferramentas do mgt-login
Microsoft Graph pode ser usado para autenticar usuários e recuperar um token de acesso. Em seguida, o token de acesso pode ser usado para fazer chamadas para o Microsoft Graph.
Observação
Se você for novo no Microsoft Graph, saiba mais sobre ele no roteiro de aprendizagem de Conceitos Básicos do Microsoft Graph .
Neste exercício, você vai:
- Saiba como associar um aplicativo Microsoft Entra ID ao Kit de Ferramentas do Microsoft Graph para que ele possa ser usado 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 entrada
No exercício anterior, você criou um registro de aplicativo no Microsoft Entra ID 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>
Verifique se você concluiu o exercício anterior antes de continuar.
Voltar para o navegador (http://localhost:4200), selecione Entrar no cabeçalho e entre usando uma conta de usuário administrador do locatário do Desenvolvedor do Microsoft 365.
Dica
Entre com sua conta de administrador de locatário do desenvolvedor do Microsoft 365. Você pode exibir outros usuários no locatário do desenvolvedor acessando o Centro de administração do Microsoft 365.
Se você estiver entrando no aplicativo pela primeira vez, será solicitado que você consenta com as permissões solicitadas pelo aplicativo. Você aprenderá mais sobre essas permissões (também chamadas de "escopos") na próxima seção enquanto explora o código. Selecione Aceitar para continuar.
Depois de entrar, você deverá ver o nome do usuário exibido no cabeçalho.
Explorando o código de entrada
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 Kit de Ferramentas do Microsoft Graph.
Dica
Se você estiver usando Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que você deseja abrir.
Abra o cliente/package.json e observe que o
@microsoft/mgt
pacote está incluído nas dependências. Esse pacote contém recursos do provedor MSAL (Biblioteca de Autenticação da Microsoft), bem como componentes da Web, como mgt-login e outros que podem ser usados para conectar usuários e recuperar e exibir dados organizacionais.Para usar o componente mgt-login para conectar usuários, a ID do cliente do aplicativo Microsoft Entra ID (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á o seguinte código: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'] });
Esse código cria um novo
Msal2Provider
objeto, passando o Microsoft Entra ID ID do cliente do registro do aplicativo e o para oscopes
qual o aplicativo solicitará acesso. Osscopes
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 Kit de Ferramentas do Microsoft Graph para recuperar dados do Microsoft Graph.Abra header.component.html no editor e localize o componente mgt-login . O caminho completo para o arquivo é client/src/app/header/header.component.html.
<mgt-login *ngIf="featureFlags.microsoft365Enabled" class="mgt-dark" (loginCompleted)="loginCompleted()"></mgt-login>
O componente mgt-login permite que o usuário entre e acesse a recuperação de token para uso com o Microsoft Graph. Após a entrada bem-sucedida, o
loginCompleted
evento é disparado, chamando posteriormente aloginCompleted()
função . Embora o mgt-login seja usado em um componente Angular neste exemplo, ele é compatível com qualquer aplicativo 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 deENTRAID_CLIENT_ID
ambiente para confirmar se o aplicativo está configurado corretamente e capaz de se autenticar em Microsoft Entra ID. 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.Abra header.component.ts e localize a
loginCompleted
função. Essa função é chamada quando ologinCompleted
evento é emitido e usado para recuperar o 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 à API do Microsoft Graph
me
para recuperar seu perfil de usuário (me
representa o usuário conectado atual). Athis.userLoggedIn.emit(me)
instrução code 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 Kit de Ferramentas do Microsoft Graph .
Agora que você fez logon no aplicativo, vamos examinar 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 variedade de dados organizacionais, incluindo emails, chats, arquivos, eventos de calendário e muito mais. Isso pode levar a mudanças de contexto frequentes, 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 mudar de seu aplicativo atual para o Outlook para encontrar detalhes cruciais em um email ou mudar para OneDrive for Business para encontrar um arquivo relacionado. Essa ação de ida e volta interrompe o foco e perde tempo que poderia ser melhor gasto na tarefa em questão.
Para aumentar a eficiência, você pode integrar dados organizacionais diretamente aos 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 de forma mais direta, minimizando as mudanças de contexto e melhorando a produtividade. Além disso, essa integração fornece insights e contexto valiosos, permitindo que os usuários tome decisões informadas e trabalhem com mais eficiência.
Neste exercício, você vai:
- Saiba como o componente Web mgt-search-results no Kit de Ferramentas do Microsoft Graph pode ser usado para pesquisar arquivos.
- Saiba como chamar o Microsoft Graph diretamente para recuperar arquivos de 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.
Observação
O componente mgt-search-results está atualmente em versão prévia e está sujeito a alterações. Além de mostrar como mgt-search-results pode ser usado, os exercícios também mostram como executar as mesmas tarefas usando o Microsoft Graph diretamente.
Usando o recurso de dados organizacionais
Em um exercício anterior, você criou um registro de aplicativo no Microsoft Entra ID 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>
Verifique se você concluiu o exercício anterior antes de continuar.
Voltar para o navegador (http://localhost:4200). Se você ainda não entrou, selecione Entrar no cabeçalho e entre com um usuário no locatário do Desenvolvedor do Microsoft 365.
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 da Adatum Corporation no datagrid. 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 datagrid em uma interface com guias. É importante menção que talvez você não veja 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 dados organizacionais relacionados para a Adatum Corporation neste estágio. Para adicionar alguns dados de exemplo, execute pelo menos uma das seguintes ações:
Adicione arquivos visitando e entrando https://onedrive.com usando suas credenciais de locatário do Microsoft 365 Developer.
- Selecione Meus arquivos no painel de navegação esquerdo.
- Selecione Carregar e, em seguida , Pasta no menu.
- Selecione a pasta de documentos openai-acs-msgraph/customer no projeto clonado.
Adicione mensagens de chat e eventos de calendário visitando https://teams.microsoft.com e entrando usando suas credenciais de locatário do Desenvolvedor do Microsoft 365.
Selecione Teams no painel de navegação esquerdo.
Selecione uma equipe e um canal.
Selecione Nova conversa.
Insira Novo pedido feito para a Adatum Corporation e selecione o botão Enviar.
Fique à vontade para adicionar mensagens de chat adicionais que menção outras empresas usadas no aplicativo, como Adventure Works Cycles, Contoso Pharmaceuticals e Tailwind Traders.
Selecione Calendário no painel de navegação esquerdo.
Selecione Nova reunião.
Insira "Reunir-se com a Adatum Corporation sobre o agendamento do projeto" para o título e o corpo.
Clique em Salvar.
Adicione emails visitando e entrando https://outlook.com usando suas credenciais de locatário do Desenvolvedor do Microsoft 365.
Selecione Novo email.
Insira seu endereço de email pessoal no campo Para .
Insira Novo pedido feito para a Adatum Corporation para o assunto e qualquer coisa que você gostaria para o corpo.
Selecione Enviar.
Voltar ao aplicativo no navegador e atualize a página. Selecione Exibir Conteúdo Relacionado novamente para a linha da Adatum Corporation . Agora você deverá 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 às APIs do Microsoft Graph.
Explorando o código de pesquisa de arquivos
Dica
Se você estiver usando Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que você deseja abrir.
Vamos começar examinando como os dados de arquivo são recuperados de OneDrive for Business. Abra files.component.html e reserve um momento para analisar 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 Kit de Ferramentas do Microsoft Graph e, como o nome indica, ele é usado para exibir os resultados da 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 ser pesquisado. 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 é associado àsearchText
propriedade que é passada para o componente de arquivos quando o usuário seleciona Exibir Conteúdo Relacionado para uma linha no datagrid. 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 ao redordataChange
indicam que o evento está associado àdataChange()
função.Como nenhum modelo personalizado é fornecido, o modelo padrão interno
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ê observará que um
query
parâmetro é passado para a função . Esse é o termo de pesquisa passado à medida que o usuário seleciona Exibir Conteúdo Relacionado para uma linha no datagrid. 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á pesquisando arquivos no OneDrive for Business então
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. Emquery
seguida, o parâmetro é adicionado aoqueryString
filtro junto comContentType:Document
.const filter = { "requests": [ { "entityTypes": [ "driveItem" ], "query": { "queryString": `${query} AND ContentType:Document` } } ] };
Em seguida, uma chamada é feita para o
/search/query
Microsoft API do 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 iterados por meio de para localizar
hits
. Cadahit
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); } } } }
Em
files
seguida, a matriz é retornada ao chamador.return files;
Examinando esse 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 à 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 ao Microsoft Graph quando o usuário seleciona Exibir Conteúdo Relacionado para uma linha no datagrid. A
search()
função chamasearchFiles()
em graph.service.ts e passa oquery
parâmetro para ele (o nome da empresa neste exemplo). Os resultados da pesquisa sã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 Kit de Ferramentas do Microsoft Graph chamadomgt-file-list
. Aqui está um exemplo de associação dadata
propriedade a uma das propriedades do componente chamadafiles
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 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
Voltar 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 ,teamId
channelId
emessageId
são passadas. Isso retorna os detalhes completos da mensagem. - Tarefas de filtragem adicionais são executadas e as mensagens resultantes são retornadas de
searchChatMessages()
para 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()
em 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 associação de dados é usada para iterar pela matriz de resultados e renderizar os dados. Este exemplo usa um componente cartão material Angular para exibir os resultados da pesquisa.<div *ngIf="data.length"> <mat-card *ngFor="let chatMessage of data"> <mat-card-header> <mat-card-title [innerHTML]="chatMessage.summary"></mat-card-title> </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 chat 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 podem ser recuperados dinamicamente, bem como usando o Microsoft Graph. Abody
constante contém a mensagem a ser enviada. Em seguida, 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 o productivbity do usuário, permitindo que os usuários interajam com o Microsoft Teams diretamente do aplicativo que já estão usando.
Dados organizacionais: recuperando emails e eventos de calendário
No exercício anterior, você aprendeu a recuperar arquivos de 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 Kit de Ferramentas do Microsoft Graph 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 Email código de pesquisa de mensagens
Dica
Se você estiver usando Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que você deseja abrir.
Em um exercício anterior, você criou um registro de aplicativo no Microsoft Entra ID 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>
Verifique se você concluiu o exercício anterior antes de continuar.
Abra emails.component.html e reserve um momento para analisar 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 maneira que o que você examinou anteriormente. A única diferença é que o
entity-types
atributo é definido paramessage
o qual é usado para pesquisar mensagens de email 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 ser pesquisado. 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 dodataChange()
componente emails é chamada, os resultados são passados 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 associação de dados padrão (Angular é usado nesse caso, mas você pode usar qualquer biblioteca/estrutura desejada).
- O
Veja abaixo o componente mgt-search-results em emails.component.html para localizar as associações de dados usadas para renderizar as mensagens de email. Este exemplo itera pela
data
propriedade e grava o assunto do email, a visualização do corpo e um link para exibir a mensagem de email completa.<div *ngIf="data.length"> <mat-card *ngFor="let email of data"> <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 simples é 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 automaticamente oquery
valor nos campos assunto, corpo e remetente.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 emails localizado em emails.component.ts chama
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 de 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 você verá posteriormente neste exercício.
Abra calendar-events.component.html e reserve um momento para analisar o código. O caminho completo para o arquivo é client/src/app/calendar-events/calendar-events.component.html. Você verá que ele é muito semelhante aos arquivos e aos componentes de emails 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 maneira que os que você examinou anteriormente. A única diferença é que o
entity-types
atributo é definido paraevent
o qual é 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 ser pesquisado. 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 dedataChange()
calendário é chamada, os resultados são passados 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 usando a associação de dados padrão.
- O
Imediatamente abaixo do
mgt-search-results
componente no calendar-events.component.html você encontrará as associaçõ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. Funções personalizadas incluídas no componente comodayFromDateTime()
etimeRangeFromEvent()
são chamadas para formatar 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 for especificado.<div *ngIf="data.length"> <div class="root" *ngFor='let event of data'> <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"> <div *ngIf="!event.resource.bodyPreview?.includes('Join Microsoft Teams Meeting')" class="inner-circle"></div> </div> <div class="vertical-line bottom"></div> </div> <div class="details"> <div class="subject">{{ event.resource.subject }}</div> <div class="location" *ngIf="event.resource.location?.displayName"> 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> <div class="attendees" *ngIf="event.resource.attendees?.length"> <span class="attendee" *ngFor="let attendee of event.resource.attendees"> <mgt-person person-query="{{attendee.emailAddress.name}}"></mgt-person> </span> </div> <div class="online-meeting" *ngIf="event.resource.bodyPreview?.includes('Join Microsoft Teams 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
search/query
Microsoft Graph também fornece umaevents
API que também pode ser usada para pesquisar eventos de 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. Em seguida, 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; }
Aqui está um detalhamento da URL criada:
- 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 a ser pesquisado. 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 datagrid nesse caso). Acontains()
função é usada para procurar oquery
valor nasubject
propriedade do evento de 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 ao Microsoft API do Graph usando o valor deurl
e os resultados são retornados ao chamador.Assim como acontece com os componentes anteriores, o componente calendar-events (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 aplicativo do lado do servidor. Veja o tutorial a seguir para ver um exemplo de como chamar um microsoft API do 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! Você aprendeu como o Azure OpenAI pode ser usado para aumentar a produtividade do usuário, como Serviços de Comunicação do Azure pode ser usado para integrar recursos de comunicação e como as APIs e componentes do Microsoft Graph podem ser usados para recuperar e exibir dados organizacionais. Usando essas tecnologias, você pode criar soluções eficazes que aumentam a produtividade do usuário minimizando as mudanças de contexto e fornecendo informações necessárias de tomada de decisão.
Limpar recursos do Azure
Limpe seus recursos do Azure para evitar encargos adicionais para sua conta. Vá para o portal do Azure e exclua os seguintes recursos:
- O recurso Azure Cognitive Search
- O recurso de Armazenamento do Azure
- O recurso OpenAI do Azure
- O recurso Serviços de Comunicação do Azure
Próximas etapas
Documentação
- Documentação do Azure OpenAI
- OpenAI do Azure em seus dados
- Documentação do Serviços de Comunicação do Azure
- Documentação do Microsoft Graph
- Documentação do Kit de Ferramentas do Microsoft Graph
- Documentação do desenvolvedor do Microsoft Teams
Conteúdo dos Treinamentos
- Aplicar engenharia de prompts com o Serviço de 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
- Explorar cenários do Microsoft Graph para desenvolvimento em JavaScript
- Explorar cenários do Microsoft Graph para desenvolvimento de ASP.NET Core
- Introdução ao kit de ferramentas do Microsoft Graph
- 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.