Integre recursos de OpenAI, comunicação e dados organizacionais em um aplicativo de linha de negócios
Nível: Intermédio
Este tutorial demonstra como o Azure OpenAI, os Serviços de Comunicação do Azure e o Microsoft Graph/Microsoft Graph Toolkit podem ser integrados em um aplicativo de Linha de Negócios (LOB) para melhorar a produtividade do usuário, elevar a experiência do usuário e levar os aplicativos LOB para o próximo nível. Os principais recursos do aplicativo incluem:
- AI: Permita que os usuários façam perguntas em linguagem natural e convertam suas respostas em SQL que podem ser usadas para consultar um banco de dados, permita que os usuários definam regras que podem ser usadas para gerar automaticamente mensagens de e-mail e SMS e aprenda como a linguagem natural pode ser usada para recuperar dados de suas próprias fontes de dados personalizadas. O Azure OpenAI é usado para esses recursos.
- Comunicação: habilite chamadas telefônicas no aplicativo para clientes e a funcionalidade de Email/SMS usando os Serviços de Comunicação do Azure.
- Dados organizacionais: extraia dados organizacionais relacionados que os usuários podem precisar (documentos, chats, e-mails, eventos de calendário) enquanto trabalham com os clientes para evitar a mudança de contexto. Fornecer acesso a este tipo de dados organizacionais reduz a necessidade de o usuário mudar para o Outlook, Teams, OneDrive, outros aplicativos personalizados, seu telefone, etc., uma vez que os dados específicos e a funcionalidade de que eles 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 de gerenciamento de clientes simples que permite aos usuários gerenciar seus clientes e dados relacionados. Ele consiste em um front-end construído usando TypeScript que chama APIs de back-end para recuperar dados, interagir com a funcionalidade de IA, enviar mensagens de e-mail/SMS e extrair dados organizacionais. Aqui está uma visão geral da solução de aplicativo que você verá 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 seja obrigado a copiar e colar código, alguns dos exercícios farão com que você modifique o código para experimentar diferentes cenários.
O que você vai construir neste tutorial
Escolha a sua própria aventura
Você pode completar todo o tutorial do início ao fim ou completar tópicos específicos de interesse. O tutorial é dividido nos seguintes tópicos:
- Clone o Exercício do Projeto (exercício obrigatório).
- Exercícios de IA: crie um recurso 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 dos Serviços de Comunicação do Azure e use-o para fazer chamadas telefônicas do aplicativo e enviar mensagens de email/SMS.
- Exercícios de dados organizacionais: crie um registro de aplicativo Microsoft Entra ID para que o Microsoft Graph e o Microsoft Graph Toolkit possam ser usados para autenticar e extrair dados organizacionais para o aplicativo.
Pré-requisitos
- Nó - Nó 20+ e npm 10+ serão usados para este projeto
- git
- Visual Studio Code (embora o Visual Studio Code seja recomendado, qualquer editor pode ser usado)
- Subscrição do Azure
- Locatário do desenvolvedor do Microsoft 365
- Docker Desktop ou outro tempo de execução de contêiner compatível com OCI (Open Container Initiative), como o Podman, ou nerdctl capaz de executar um contêiner.
Tecnologias de nuvem da Microsoft usadas neste tutorial
- Azure Communication Services
- Azure OpenAI Service
- Microsoft Entra ID
- Microsoft Graph
- Conjunto de ferramentas Microsoft Graph
Clone o Projeto
O projeto de código usado neste tutorial está disponível em https://github.com/microsoft/MicrosoftCloud. O repositório do projeto inclui o código do lado do cliente e do lado do servidor necessário para executar o projeto, permitindo que você explore os recursos integrados relacionados à inteligência artificial (IA), comunicação e dados organizacionais. Além disso, o projeto serve como recurso para guiá-lo na incorporação de recursos semelhantes em seus próprios aplicativos.
Neste exercício, vai:
- Clone o repositório do GitHub.
- Adicione um arquivo .env ao projeto e atualize-o.
Antes de continuar, certifique-se de ter todos os pré-requisitos instalados e configurados, conforme descrito na seção Pré-requisitos deste tutorial.
Clone o repositório GitHub e crie um .env
arquivo
Execute o seguinte comando para clonar o Microsoft Cloud GitHub Repository para sua máquina.
git clone https://github.com/microsoft/MicrosoftCloud
Abra a pasta MicrosoftCloud/samples/openai-acs-msgraph no Visual Studio Code.
Nota
Embora usemos o Visual Studio Code ao longo deste tutorial, qualquer editor de código pode ser usado para trabalhar com o projeto de exemplo.
Observe as seguintes pastas e arquivos:
- client: Código do aplicativo do lado do cliente.
- server: Código da API do lado do servidor.
- docker-compose.yml: Usado para executar um banco de dados PostgreSQL local.
Renomeie o .env.example na raiz do projeto para .env.
Abra o arquivo .env e reserve um momento para examinar as chaves que estão incluídas:
ENTRAID_CLIENT_ID= TEAM_ID= CHANNEL_ID= OPENAI_API_KEY= OPENAI_ENDPOINT= OPENAI_MODEL=gpt-4o OPENAI_API_VERSION=2024-05-01-preview POSTGRES_USER= POSTGRES_PASSWORD= ACS_CONNECTION_STRING= ACS_PHONE_NUMBER= ACS_EMAIL_ADDRESS= CUSTOMER_EMAIL_ADDRESS= CUSTOMER_PHONE_NUMBER= API_PORT=3000 AZURE_AI_SEARCH_ENDPOINT= AZURE_AI_SEARCH_KEY= AZURE_AI_SEARCH_INDEX=
Atualize os seguintes valores em .env. Esses valores serão usados pelo servidor de API para se conectar ao banco de dados PostgreSQL local.
POSTGRES_USER=web POSTGRES_PASSWORD=web-password
Agora que você já tem o projeto pronto, vamos experimentar alguns dos recursos do aplicativo e aprender como eles são construídos. Selecione o botão Avançar abaixo para continuar ou saltar para um exercício específico usando o índice.
AI: Criar um recurso OpenAI do Azure e implantar um modelo
Para começar a usar o Azure OpenAI em seus aplicativos, você precisa criar um Serviço OpenAI do Azure e implantar um modelo que possa ser usado para executar tarefas como converter linguagem natural em SQL, gerar conteúdo de mensagens de email/SMS e muito mais.
Neste exercício, vai:
- Crie um recurso do Serviço OpenAI do Azure.
- Implante um modelo.
- Atualize o arquivo .env com valores do seu recurso de serviço OpenAI do Azure.
Criar um recurso de serviço OpenAI do Azure
Visite o portal do Azure no seu browser e inicie sessão.
Digite openai na barra de pesquisa na parte superior da página do portal e selecione Azure OpenAI nas opções que aparecem.
Selecione Criar na barra de ferramentas.
Nota
Embora este tutorial se concentre no Azure OpenAI, se você tiver uma chave de API OpenAI e quiser usá-la, poderá pular esta seção e ir diretamente para a seção Atualizar o arquivo .env do projeto abaixo. Atribua sua chave de API OpenAI no
OPENAI_API_KEY
arquivo .env (você pode ignorar quaisquer outras.env
instruções relacionadas ao OpenAI).Os modelos do Azure OpenAI estão disponíveis em regiões específicas. Visite o documento de disponibilidade do modelo OpenAI do Azure para saber quais regiões suportam o modelo gpt-4o usado neste tutorial.
Execute as seguintes tarefas:
- Selecione a subscrição do Azure.
- Selecione o grupo de recursos a ser usado (crie um novo, se necessário).
- Selecione uma região onde o modelo gpt-4o é suportado com base no documento que você examinou anteriormente.
- Insira o nome do recurso. Tem de ser um valor exclusivo.
- Selecione o nível de preço Standard S0 .
Selecione Avançar até chegar à tela Revisão + envio. Selecione Criar.
Depois que seu recurso do Azure OpenAI for criado, navegue até ele e selecione Gerenciamento de Recursos -->Chaves e Ponto de Extremidade .
Localize os valores KEY 1 e Endpoint . Você usará ambos os valores na próxima seção, portanto, copie-os para um arquivo local.
Selecione Gerenciamento de recursos -->Implantações de modelo.
Selecione o botão Gerenciar implantações para ir para o Azure OpenAI Studio.
Selecione Implantar modelo -->Implantar modelo base na barra de ferramentas.
Selecione gpt-4o na lista de modelos e selecione Confirmar.
Nota
O Azure OpenAI suporta vários tipos diferentes de modelos. Cada modelo pode ser usado para lidar com diferentes cenários.
A caixa de diálogo a seguir será exibida. Reserve um momento para examinar os valores padrão fornecidos.
Altere o valor de Limite de Taxa de Tokens por Minuto (milhares) para 100K. Isso permitirá que você faça mais solicitações para o modelo e evite atingir o limite de taxa à medida que executa as etapas a seguir.
Selecione Implementar.
Depois que o modelo for implantado, selecione Playgrounds -->Chat.
A lista suspensa Implantação deve exibir o modelo gpt-4o .
Reserve um momento para ler o texto da mensagem do sistema que é fornecido. Isso informa ao modelo como agir à medida que o usuário interage com ele.
Localize a caixa de texto na área de chat e digite Resumir o que é IA Generativa e como ela pode ser usada. Selecione Enter para enviar a mensagem ao modelo e fazer com que ele gere uma resposta.
Experimente outros prompts e respostas. Por exemplo, digite Forneça um breve histórico sobre a capital da França e observe a resposta gerada.
Atualizar o arquivo do .env
projeto
Volte para Visual Studio Code e abra o
.env
arquivo na raiz do projeto.Copie o valor KEY 1 do seu recurso OpenAI do Azure e atribua-o no
OPENAI_API_KEY
arquivo .env localizado na raiz da pasta openai-acs-msgraph:OPENAI_API_KEY=<KEY_1_VALUE>
Copie o valor *Endpoint e atribua-o no
OPENAI_ENDPOINT
arquivo .env. Remova o/
caractere do final do valor se ele estiver presente.OPENAI_ENDPOINT=<ENDPOINT_VALUE>
Nota
Você verá que os valores para
OPENAI_MODEL
eOPENAI_API_VERSION
já estão definidos no arquivo .env. O valor do modelo é definido como gpt-4o , que corresponde ao nome de implantação do modelo criado anteriormente neste exercício. A versão da API é definida como um valor suportado definido na documentação de referência do Azure OpenAI.Guarde o ficheiro .env.
Iniciar os serviços de aplicativo
É 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 de código do Visual Studio e selecione Abrir no Terminal integrado. Certifique-se de que seu 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 o Docker Desktop, o Podman, o nerdctl ou outro tempo de execução de contêiner instalado, execute o seguinte comando na janela do terminal:
Subsistema Mac, Linux ou Windows para Linux (WSL):
[docker | podman | nerdctl] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v $(pwd)/data:/var/lib/postgresql/data -p 5432:5432 postgres
Windows com PowerShell:
[docker | podman] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v ${PWD}/data:/var/lib/postgresql/data -p 5432:5432 postgres
Quando o contêiner de banco de dados for iniciado, pressione o + ícone na barra de ferramentas Terminal de código do Visual Studio para criar uma segunda janela de terminal.
cd
na pasta server/typescript e execute os seguintes comandos para instalar as dependências e iniciar o servidor API.npm install
npm start
Pressione o + ícone novamente na barra de ferramentas Terminal de código do Visual Studio para criar uma terceira janela do terminal.
cd
na pasta cliente e execute os seguintes comandos para instalar as dependências e iniciar o servidor Web.npm install
npm start
Um navegador será iniciado e você será direcionado para http://localhost:4200.
AI: Linguagem Natural para SQL
A citação "Só porque você pode não significa que deveria" é um guia útil quando se pensa em 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 e, ao mesmo tempo, discutirá considerações importantes a 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 grades de dados e filtros restritos. Essa abordagem simplificada pode aumentar a produtividade, eliminando a necessidade de os usuários procurarem assistência de especialistas técnicos.
Este exercício fornece um ponto de partida que irá ajudá-lo a entender como a linguagem natural para SQL funciona, apresentá-lo a algumas considerações importantes, levá-lo a pensar sobre prós e contras e mostrar-lhe o código para começar.
Neste exercício, irá:
- Use prompts GPT para converter linguagem natural em SQL.
- Experimente diferentes prompts GPT.
- Use o SQL gerado para consultar o banco de dados PostgreSQL iniciado anteriormente.
- Retornar resultados de consulta do PostgreSQL e exibi-los no navegador.
Vamos começar experimentando diferentes prompts GPT que podem ser usados para converter linguagem natural em SQL.
Usando o recurso de linguagem natural para SQL
No exercício anterior, você iniciou o banco de dados, as APIs e o aplicativo. Você também atualizou o
.env
arquivo. Se você não concluiu essas etapas, siga as instruções no final do exercício antes de continuar.Volte para o navegador (http://localhost:4200) e localize a seção Consulta personalizada da página abaixo da grade de dados. Observe que um valor de consulta de exemplo já está incluído: Obtenha a receita total para todos os pedidos. Grupo por empresa e incluir a cidade.
Selecione o botão Executar consulta . Isso passará a consulta de linguagem natural do usuário para o Azure OpenAI, que a converterá em SQL. A consulta SQL será então 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 ele exibe a consulta SQL retornada do Azure OpenAI. Os dados JSON são usados pelas APIs do lado do servidor para consultar o banco de dados PostgreSQL. Todos os valores de cadeia de caracteres incluídos na consulta são adicionados como valores de parâmetro para evitar ataques de injeção de SQL:
{ "sql": "SELECT c.company, c.city, c.email, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.company = $1 GROUP BY c.company, c.city, c.email", "paramValues": ["Adventure Works Cycles"] }
Volte para o navegador e selecione Redefinir dados para visualizar todos os clientes novamente na grade de dados.
Explorando a linguagem natural para o código SQL
Gorjeta
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Nota
O objetivo deste exercício é mostrar o que é possível com a funcionalidade de linguagem natural para SQL e demonstrar como começar a usá-la. Como mencionado anteriormente, é importante discutir se esse tipo de IA é apropriado para sua organização antes de prosseguir com qualquer implementação. Também é imperativo planejar regras rápidas adequadas e medidas de segurança de banco de dados para evitar o acesso não autorizado e proteger dados confidenciais.
Agora que você viu o recurso de linguagem natural para SQL em ação, vamos examinar como ele é implementado.
Abra o arquivo server/apiRoutes.ts e localize a
generateSql
rota. Essa rota de API é chamada pelo aplicativo do lado do cliente em execução no navegador e usada para gerar SQL a partir de uma consulta de linguagem natural. Depois que a consulta SQL é recuperada, ela é usada para consultar o banco de dados e retornar resultados.router.post('/generateSql', async (req, res) => { const userPrompt = req.body.prompt; if (!userPrompt) { return res.status(400).json({ error: 'Missing parameter "prompt".' }); } try { // Call Azure OpenAI to convert the user prompt into a SQL query const sqlCommandObject = await getSQLFromNLP(userPrompt); let result: any[] = []; // Execute the SQL query if (sqlCommandObject && !sqlCommandObject.error) { result = await queryDb(sqlCommandObject) as any[]; } else { result = [ { query_error : sqlCommandObject.error } ]; } res.json(result); } catch (e) { console.error(e); res.status(500).json({ error: 'Error generating or running SQL query.' }); } });
Observe a seguinte funcionalidade na
generateSql
rota:- Ele recupera o valor de consulta do
req.body.prompt
usuário e o atribui a uma variável chamadauserPrompt
. Esse valor será usado no prompt GPT. - Ele chama uma função para converter linguagem
getSQLFromNLP()
natural para SQL. - Ele passa o SQL gerado para uma função chamada
queryDb
que executa a consulta SQL e retorna resultados do banco de dados.
- Ele recupera o valor de consulta do
Abra o arquivo servidor/openAI.ts em seu editor e localize a
getSQLFromNLP()
função. Esta função é chamada pelageneratesql
rota e é usada para converter linguagem natural em SQL.async function getSQLFromNLP(userPrompt: string): Promise<QueryData> { // Get the high-level database schema summary to be used in the prompt. // The db.schema file could be generated by a background process or the // schema could be dynamically retrieved. const dbSchema = await fs.promises.readFile('db.schema', 'utf8'); const systemPrompt = ` Assistant is a natural language to SQL bot that returns a JSON object with the SQL query and the parameter values in it. The SQL will query a PostgreSQL database. PostgreSQL tables with their columns: ${dbSchema} Rules: - Convert any strings to a PostgreSQL parameterized query value to avoid SQL injection attacks. - Return a JSON object with the following structure: { "sql": "", "paramValues": [] } Examples: User: "Display all company reviews. Group by company." Assistant: { "sql": "SELECT * FROM reviews", "paramValues": [] } User: "Display all reviews for companies located in cities that start with 'L'." Assistant: { "sql": "SELECT r.* FROM reviews r INNER JOIN customers c ON r.customer_id = c.id WHERE c.city LIKE 'L%'", "paramValues": [] } User: "Display revenue for companies located in London. Include the company name and city." Assistant: { "sql": "SELECT c.company, c.city, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.city = $1 GROUP BY c.company, c.city", "paramValues": ["London"] } User: "Get the total revenue for Adventure Works Cycles. Include the contact information as well." Assistant: { "sql": "SELECT c.company, c.city, c.email, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.company = $1 GROUP BY c.company, c.city, c.email", "paramValues": ["Adventure Works Cycles"] } `; let queryData: QueryData = { sql: '', paramValues: [], error: '' }; let results = ''; try { results = await callOpenAI(systemPrompt, userPrompt); if (results) { console.log('results', results); const parsedResults = JSON.parse(results); queryData = { ...queryData, ...parsedResults }; if (isProhibitedQuery(queryData.sql)) { queryData.sql = ''; queryData.error = 'Prohibited query.'; } } } catch (error) { console.log(error); if (isProhibitedQuery(results)) { queryData.sql = ''; queryData.error = 'Prohibited query.'; } else { queryData.error = results; } } return queryData; }
- Um
userPrompt
parâmetro é passado para a função. OuserPrompt
valor é a consulta em linguagem natural inserida pelo usuário no navegador. - A
systemPrompt
define o tipo de assistente de IA a ser usado e as regras que devem ser seguidas. Isso ajuda o Azure OpenAI a entender a estrutura do banco de dados, quais regras aplicar e como retornar a consulta SQL e os parâmetros gerados. - Uma função chamada
callOpenAI()
é chamada e os valores euserPrompt
são passadossystemPrompt
para ela. - Os resultados são verificados para garantir que nenhum valor proibido seja incluído na consulta SQL gerada. Se valores proibidos forem encontrados, a consulta SQL será definida como uma cadeia de caracteres vazia.
- Um
Vamos percorrer o prompt do sistema com mais detalhes:
const systemPrompt = ` Assistant is a natural language to SQL bot that returns a JSON object with the SQL query and the parameter values in it. The SQL will query a PostgreSQL database. PostgreSQL tables with their columns: ${dbSchema} Rules: - Convert any strings to a PostgreSQL parameterized query value to avoid SQL injection attacks. - Return a JSON object with the following structure: { "sql": "", "paramValues": [] } Examples: User: "Display all company reviews. Group by company." Assistant: { "sql": "SELECT * FROM reviews", "paramValues": [] } User: "Display all reviews for companies located in cities that start with 'L'." Assistant: { "sql": "SELECT r.* FROM reviews r INNER JOIN customers c ON r.customer_id = c.id WHERE c.city LIKE 'L%'", "paramValues": [] } User: "Display revenue for companies located in London. Include the company name and city." Assistant: { "sql": "SELECT c.company, c.city, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.city = $1 GROUP BY c.company, c.city", "paramValues": ["London"] } User: "Get the total revenue for Adventure Works Cycles. Include the contact information as well." Assistant: { "sql": "SELECT c.company, c.city, c.email, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.company = $1 GROUP BY c.company, c.city, c.email", "paramValues": ["Adventure Works Cycles"] } `;
O tipo de assistente de IA a ser usado é definido. Neste caso, um "bot de linguagem natural para SQL".
Os nomes das tabelas e as colunas no banco de dados são definidos. O esquema de alto nível incluído no prompt pode ser encontrado no arquivo server/db.schema e se parece com o seguinte.
- customers (id, company, city, email) - orders (id, customer_id, date, total) - order_items (id, order_id, product_id, quantity, price) - reviews (id, customer_id, review, date, comment)
Gorjeta
Você pode considerar a criação de exibições somente leitura que contenham apenas os dados que os usuários têm permissão para consultar usando linguagem natural para SQL.
Uma regra é definida para converter quaisquer valores de cadeia de caracteres em um valor de consulta parametrizado para evitar ataques de injeção de SQL.
Uma regra é definida para sempre retornar um objeto JSON com a consulta SQL e os valores de parâmetro nela.
Exemplos de prompts do usuário e a consulta SQL esperada e os valores de parâmetro são fornecidos. Isso é conhecido como aprendizagem de "poucos tiros". Embora os LLMs sejam treinados em grandes quantidades de dados, eles podem ser adaptados a novas tarefas com apenas alguns exemplos. Uma abordagem alternativa é a aprendizagem "zero-shot", onde nenhum exemplo é fornecido e espera-se que o modelo gere a consulta SQL correta e os valores de parâmetro.
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 server/openAI.ts . AcallOpenAI()
função determina se o serviço OpenAI do Azure ou o serviço OpenAI deve ser chamado verificando variáveis de ambiente. Se uma chave, ponto de extremidade e modelo estiverem disponíveis nas variáveis de ambiente, o Azure OpenAI será chamado, caso contrário, o OpenAI será chamado.function callOpenAI(systemPrompt: string, userPrompt: string, temperature = 0, useBYOD = false) { const isAzureOpenAI = OPENAI_API_KEY && OPENAI_ENDPOINT && OPENAI_MODEL; if (isAzureOpenAI) { if (useBYOD) { return getAzureOpenAIBYODCompletion(systemPrompt, userPrompt, temperature); } return getAzureOpenAICompletion(systemPrompt, userPrompt, temperature); } return getOpenAICompletion(systemPrompt, userPrompt, temperature); }
Nota
Embora nos concentremos no Azure OpenAI ao longo deste tutorial, se você fornecer apenas um
OPENAI_API_KEY
valor no arquivo .env , o aplicativo usará o OpenAI em vez disso. Se você optar por usar o OpenAI em vez do Azure OpenAI, poderá ver resultados diferentes em alguns casos.Localize a
getAzureOpenAICompletion()
função.async function getAzureOpenAICompletion(systemPrompt: string, userPrompt: string, temperature: number): Promise<string> { const completion = await createAzureOpenAICompletion(systemPrompt, userPrompt, temperature); let content = completion.choices[0]?.message?.content?.trim() ?? ''; console.log('Azure OpenAI Output: \n', content); if (content && content.includes('{') && content.includes('}')) { content = extractJson(content); } return content; }
Esta função faz o seguinte:
Parâmetros:
systemPrompt
,userPrompt
etemperature
são os principais parâmetros.systemPrompt
: Informa o modelo OpenAI do Azure sobre o seu papel e as regras a seguir.userPrompt
: Contém as informações fornecidas pelo usuário, como entrada em linguagem natural ou regras para gerar a saída.temperature
: Dita o nível de criatividade da resposta do modelo. Um valor mais elevado resulta em saídas mais criativas.
Geração de conclusão:
- A função chama
createAzureOpenAICompletion()
comsystemPrompt
,userPrompt
etemperature
para gerar uma conclusão. - Ele extrai o conteúdo da primeira escolha na conclusão, cortando qualquer espaço em branco extra.
- Se o conteúdo contiver estruturas semelhantes a JSON (indicadas pela presença de
{
e}
), ele extrai o conteúdo JSON.
- A função chama
Valor de registro e retorno:
- A função registra a saída do Azure OpenAI no console.
- Ele retorna o conteúdo processado como uma cadeia de caracteres.
Localize a
createAzureOpenAICompletion()
função.async function createAzureOpenAICompletion(systemPrompt: string, userPrompt: string, temperature: number, dataSources?: any[]): Promise<any> { const baseEnvVars = ['OPENAI_API_KEY', 'OPENAI_ENDPOINT', 'OPENAI_MODEL']; const byodEnvVars = ['AZURE_AI_SEARCH_ENDPOINT', 'AZURE_AI_SEARCH_KEY', 'AZURE_AI_SEARCH_INDEX']; const requiredEnvVars = dataSources ? [...baseEnvVars, ...byodEnvVars] : baseEnvVars; checkRequiredEnvVars(requiredEnvVars); const config = { apiKey: OPENAI_API_KEY, endpoint: OPENAI_ENDPOINT, apiVersion: OPENAI_API_VERSION, deployment: OPENAI_MODEL }; const aoai = new AzureOpenAI(config); const completion = await aoai.chat.completions.create({ model: OPENAI_MODEL, // gpt-4o, gpt-3.5-turbo, etc. Pulled from .env file max_tokens: 1024, temperature, response_format: { type: "json_object", }, messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt } ], // @ts-expect-error data_sources is a custom property used with the "Azure Add Your Data" feature data_sources: dataSources }); return completion; } function checkRequiredEnvVars(requiredEnvVars: string[]) { for (const envVar of requiredEnvVars) { if (!process.env[envVar]) { throw new Error(`Missing ${envVar} in environment variables.`); } } }
Esta função faz o seguinte:
Parâmetros:
systemPrompt
,userPrompt
etemperature
são os principais parâmetros discutidos anteriormente.- Um parâmetro opcional
dataSources
dá suporte ao recurso "Azure Bring Your Own Data", que será abordado mais adiante neste tutorial.
Verificação de variáveis de ambiente:
- A função verifica a presença de variáveis de ambiente essenciais, lançando um erro se alguma estiver faltando.
Objeto de configuração:
- Um
config
objeto é criado usando valores do.env
arquivo (OPENAI_API_KEY
,OPENAI_ENDPOINT
,OPENAI_API_VERSION
,OPENAI_MODEL
). Esses valores são usados para construir a URL para chamar o Azure OpenAI.
- Um
Instância do AzureOpenAI:
- Uma instância de
AzureOpenAI
é criada usando oconfig
objeto. OAzureOpenAI
símbolo faz parte doopenai
pacote, que deve ser importado na parte superior do arquivo.
- Uma instância de
Gerando uma conclusão:
- A
chat.completions.create()
função é chamada com as seguintes propriedades:model
: Especifica o modelo GPT (por exemplo, gpt-4o, gpt-3.5-turbo) conforme definido no seu.env
ficheiro.max_tokens
: Define o número máximo de tokens para a conclusão.temperature
: Define a temperatura de amostragem. Valores mais altos (por exemplo, 0,9) produzem respostas mais criativas, enquanto valores mais baixos (por exemplo, 0) produzem respostas mais determinísticas.response_format
: Define o formato de resposta. Aqui, ele é definido para retornar um objeto JSON. Mais detalhes sobre o modo JSON podem ser encontrados na documentação de referência do Azure OpenAI.messages
: Contém as mensagens para gerar a conclusão do chat. Este exemplo inclui duas mensagens: uma do sistema (definindo comportamento e regras) e outra do usuário (contendo o texto do prompt).
- A
Valor de retorno:
- A função retorna o objeto de conclusão gerado pelo Azure OpenAI.
Comente as seguintes linhas na
getSQLFromNLP()
função:// if (isProhibitedQuery(queryData.sql)) { // queryData.sql = ''; // }
Poupe openAI.ts. O servidor de API reconstruirá automaticamente o código TypeScript e reiniciará o servidor.
Volte para o navegador e digite Selecionar todos os nomes de tabela do banco de dados na entrada Consulta personalizada . Selecione Executar consulta. Os nomes das tabelas são exibidos?
Volte para a
getSQLFromNLP()
função no servidor/openAI.ts e adicione a seguinte regra na seção do prompt do sistema e, emRules:
seguida, salve o arquivo.- Do not allow the SELECT query to return table names, function names, or procedure names.
Volte ao 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 das tabelas são exibidos?
- Digite Selecione todos os nomes de funções do banco de dados. na entrada Consulta personalizada e selecione Executar consulta novamente. Os nomes das funções são exibidos?
PERGUNTA: Um modelo sempre seguirá as regras definidas no prompt?
RESPOSTA: Não! É importante notar que os modelos OpenAI podem retornar resultados inesperados em ocasiões que podem não corresponder às regras que você definiu. É importante planejar isso em seu código.
Volte para o servidor/openAI.ts e localize a
isProhibitedQuery()
função. Este é um exemplo de código de pós-processamento que pode ser executado depois que o Azure OpenAI retorna resultados. Observe que ele define asql
propriedade como uma cadeia de caracteres vazia se palavras-chave proibidas forem retornadas na consulta SQL gerada. Isso garante que, se resultados inesperados forem retornados do Azure OpenAI, a consulta SQL não será executada no banco de dados.function isProhibitedQuery(query: string): boolean { if (!query) return false; const prohibitedKeywords = [ 'insert', 'update', 'delete', 'drop', 'truncate', 'alter', 'create', 'replace', 'information_schema', 'pg_catalog', 'pg_tables', 'pg_proc', 'pg_namespace', 'pg_class', 'table_schema', 'table_name', 'column_name', 'column_default', 'is_nullable', 'data_type', 'udt_name', 'character_maximum_length', 'numeric_precision', 'numeric_scale', 'datetime_precision', 'interval_type', 'collation_name', 'grant', 'revoke', 'rollback', 'commit', 'savepoint', 'vacuum', 'analyze' ]; const queryLower = query.toLowerCase(); return prohibitedKeywords.some(keyword => queryLower.includes(keyword)); }
Nota
É importante notar que este é apenas um código de demonstração. Pode haver outras palavras-chave proibidas necessárias para cobrir seus casos de uso específicos se você optar por converter linguagem natural para 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 de palavras-chave proibidas, você também precisará levar em conta a segurança.
Volte para server/openAI.ts e descomente o seguinte código na
getSQLFromNLP()
função. Guarde o ficheiro.if (isProhibitedQuery(queryData.sql)) { queryData.sql = ''; }
Remova a seguinte regra e
systemPrompt
salve o arquivo.- Do not allow the SELECT query to return table names, function names, or procedure names.
Volte para o navegador, digite Selecionar todos os nomes de tabela do banco de dados na entrada Consulta personalizada novamente e selecione o botão Executar consulta .
Os resultados de alguma tabela são exibidos? Mesmo sem a regra em vigor, o
isProhibitedQuery()
código de pós-processamento proíbe que esse tipo de consulta seja executado no banco de dados.Como discutido anteriormente, a integração de linguagem natural ao SQL em aplicativos de linha de negócios pode ser bastante benéfica para os usuários, mas vem com seu próprio conjunto de considerações.
Vantagens:
Facilidade de uso: esse recurso pode tornar a interação do banco de dados mais acessível para usuários sem conhecimento técnico, reduzindo a necessidade de conhecimento 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 ter que confiar em especialistas técnicos, aumentando assim a eficiência.
Aplicação ampla: Usando modelos de linguagem avançados, os aplicativos podem ser projetados para atender a uma ampla gama de usuários e casos de uso.
Considerações:
Segurança: Uma das maiores preocupações é a segurança. Se os usuários podem interagir com bancos de dados usando linguagem natural, precisa haver medidas de segurança robustas em vigor para evitar acesso não autorizado ou consultas maliciosas. Você pode considerar a implementação de um modo somente leitura para impedir que os usuários modifiquem dados.
Privacidade de dados: certos dados podem ser confidenciais e não devem ser facilmente acessíveis, portanto, você precisará garantir que proteções adequadas e permissões de usuário estejam em vigor.
Precisão: Embora o processamento de linguagem natural tenha melhorado significativamente, não é perfeito. A interpretação incorreta das consultas do usuário pode levar a resultados imprecisos ou comportamento inesperado. Você precisará planejar como os resultados inesperados serão tratados.
Eficiência: Não há garantias de que o SQL retornado de uma consulta de linguagem natural será eficiente. Em alguns casos, chamadas adicionais para o Azure OpenAI podem ser necessárias se as regras de pós-processamento detetarem 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 considerar antes de passar para o próximo exercício:
- Lembre-se de que "Só porque você pode não significa que deve" se aplica aqui. Tenha muito cuidado e planejamento cuidadoso antes de integrar linguagem natural ao SQL em um aplicativo. É importante compreender os riscos potenciais e planeá-los.
- Antes de usar esse tipo de tecnologia, discuta cenários potenciais com sua equipe, administradores de banco de dados, equipe de segurança, partes interessadas 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 quaisquer outros requisitos que sua organização possa ter em vigor.
- A segurança deve ser uma preocupação primordial e incorporada no processo de planejamento, desenvolvimento e implantação.
- Embora a linguagem natural para SQL possa ser muito poderosa, um planejamento cuidadoso deve ser feito para garantir que os prompts tenham regras necessárias e que a funcionalidade de pós-processamento esteja incluída. Planeje tempo adicional para implementar e testar esse tipo de funcionalidade e para levar em conta cenários em que resultados inesperados são retornados.
- Com o Azure OpenAI, os clientes obtêm os recursos de segurança do Microsoft Azure enquanto executam os mesmos modelos do OpenAI. O Azure OpenAI oferece rede privada, disponibilidade regional e filtragem responsável de conteúdo de IA. Saiba mais sobre Dados, privacidade e segurança para o Serviço OpenAI do Azure.
Agora você viu como usar o Azure OpenAI para converter linguagem natural em SQL e aprendeu sobre os prós e contras da implementação desse tipo de funcionalidade. No próximo exercício, você aprenderá como as mensagens de email e SMS podem ser geradas usando o Azure OpenAI.
AI: 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 "O pedido está atrasado 5 dias" e o sistema gerará automaticamente mensagens de email e SMS contextualmente apropriadas com base nessas regras.
Esse recurso serve como um ponto de partida para os usuários, fornecendo-lhes um modelo de mensagem cuidadosamente criado que eles podem personalizar facilmente antes de enviar. O resultado é uma redução significativa no tempo e esforço necessários para compor mensagens, permitindo que os usuários se concentrem em outras tarefas importantes. Além disso, a tecnologia de geração de linguagem do Azure OpenAI pode ser integrada em fluxos de trabalho de automação, permitindo que o sistema gere e envie mensagens de forma autônoma em resposta a gatilhos predefinidos. Esse nível de automação não apenas acelera os processos de comunicação, mas também garante mensagens consistentes e precisas em vários cenários.
Neste exercício, irá:
- Experimente diferentes prompts.
- Use prompts para gerar finalizações para mensagens de e-mail e SMS.
- Explore o código que permite a conclusão de IA.
- Saiba mais sobre a importância da engenharia imediata e inclua regras em seus prompts.
Vamos começar experimentando diferentes regras que podem ser usadas para gerar mensagens de e-mail e SMS.
Usando o recurso de conclusão de IA
Em um exercício anterior, você iniciou o banco de dados, as APIs e o aplicativo. Você também atualizou o
.env
arquivo. Se você não concluiu essas etapas, siga as instruções no final do exercício antes de continuar.Volte para o navegador (http://localhost:4200) e selecione Entrar em contato com o cliente em qualquer linha na grade de dados seguida por E-mail/SMS Cliente para chegar à tela do Gerador de mensagens .
Isso usa o Azure OpenAI para converter regras de mensagem definidas em mensagens de email/SMS. Execute as seguintes tarefas:
Insira uma regra como Ordem atrasada 5 dias após a entrada e selecione o botão Gerar e-mail /mensagens SMS.
Você verá um assunto e corpo gerados para o e-mail e uma mensagem curta gerada para o SMS.
Nota
Como os Serviços de Comunicação do Azure ainda não estão habilitados, você não poderá enviar as mensagens de email ou SMS.
Feche a janela de diálogo e-mail/SMS no navegador. Agora que você já viu esse recurso em ação, vamos examinar como ele é implementado.
Explorando o código de conclusão de IA
Gorjeta
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Abra o arquivo server/apiRoutes.ts e localize a
completeEmailSmsMessages
rota. Essa API é chamada pela parte front-end do aplicativo quando o botão Gerar mensagens de e-mail/SMS é selecionado. Ele recupera os valores de prompt do usuário, empresa e nome de contato do corpo e os passa para acompleteEmailSMSMessages()
função no arquivo servidor/openAI.ts . Os resultados são então devolvidos ao cliente.router.post('/completeEmailSmsMessages', async (req, res) => { const { prompt, company, contactName } = req.body; if (!prompt || !company || !contactName) { return res.status(400).json({ status: false, error: 'The prompt, company, and contactName parameters must be provided.' }); } let result; try { // Call OpenAI to get the email and SMS message completions result = await completeEmailSMSMessages(prompt, company, contactName); } catch (e: unknown) { console.error('Error parsing JSON:', e); } res.json(result); });
Abra o arquivo server/openAI.ts e localize a
completeEmailSMSMessages()
função.async function completeEmailSMSMessages(prompt: string, company: string, contactName: string) { console.log('Inputs:', prompt, company, contactName); const systemPrompt = ` Assistant is a bot designed to help users create email and SMS messages from data and return a JSON object with the email and SMS message information in it. Rules: - Generate a subject line for the email message. - Use the User Rules to generate the messages. - All messages should have a friendly tone and never use inappropriate language. - SMS messages should be in plain text format and NO MORE than 160 characters. - Start the message with "Hi <Contact Name>,\n\n". Contact Name can be found in the user prompt. - Add carriage returns to the email message to make it easier to read. - End with a signature line that says "Sincerely,\nCustomer Service". - Return a valid JSON object with the emailSubject, emailBody, and SMS message values in it: { "emailSubject": "", "emailBody": "", "sms": "" } - The sms property value should be in plain text format and NO MORE than 160 characters. `; const userPrompt = ` User Rules: ${prompt} Contact Name: ${contactName} `; let content: EmailSmsResponse = { status: true, email: '', sms: '', error: '' }; let results = ''; try { results = await callOpenAI(systemPrompt, userPrompt, 0.5); if (results) { const parsedResults = JSON.parse(results); content = { ...content, ...parsedResults, status: true }; } } catch (e) { console.log(e); content.status = false; content.error = results; } return content; }
Esta função tem as seguintes características:
systemPrompt
é usado para definir que um assistente de IA capaz de gerar mensagens de e-mail e SMS é necessário. OsystemPrompt
também inclui:- Regras para o assistente seguir para controlar o tom das mensagens, o formato de início e fim, o comprimento máximo das mensagens SMS e muito mais.
- Informações sobre dados que devem ser incluídos na resposta - um objeto JSON neste caso.
userPrompt
é usado para definir as regras e o nome de contato que o usuário final gostaria de incluir à medida que as mensagens de e-mail e SMS são geradas. A regra Encomenda está atrasada 5 dias que introduziu anteriormente está incluída emuserPrompt
.- A função chama a
callOpenAI()
função que você explorou anteriormente para gerar as finalizações de e-mail e SMS.
Volte para o navegador, atualize a página e selecione Entrar em contato com o cliente em qualquer linha seguida por E-mail/SMS Cliente para acessar a tela do Gerador de mensagens novamente.
Insira as seguintes regras na entrada do Gerador de Mensagens :
- A encomenda está adiantada.
- Diga ao cliente para nunca mais encomendar connosco, não queremos o seu negócio.
Selecione Gerar mensagens de e-mail/SMS e anote a mensagem. A
All messages should have a friendly tone and never use inappropriate language.
regra no prompt do sistema está substituindo a regra negativa no prompt do usuário.Volte para o servidor/openAI.ts* no seu editor e remova a
All messages should have a friendly tone and never use inappropriate language.
regra do prompt nacompleteEmailSMSMessages()
função. Guarde o ficheiro.Volte para o gerador de mensagens de e-mail / SMS no navegador e execute as mesmas regras novamente:
- A encomenda está adiantada.
- Diga ao cliente para nunca mais encomendar connosco, não queremos o seu negócio.
Selecione Gerar mensagens de e-mail/SMS e observe a mensagem que é retornada.
O que está a acontecer nestes cenários? Ao usar o Azure OpenAI, a filtragem de conteúdo pode ser aplicada para garantir que a linguagem apropriada seja sempre usada. Se você estiver usando OpenAI, a regra definida no prompt do sistema é usada para garantir que a mensagem retornada seja apropriada.
Nota
Isso ilustra a importância de projetar seus prompts com as informações e regras corretas para garantir que os resultados adequados sejam retornados. Leia mais sobre esse processo na Introdução à documentação de engenharia imediata.
Desfaça as alterações feitas
systemPrompt
nocompleteEmailSMSMessages()
, salve o arquivo e execute-o novamente, mas use apenas aOrder is ahead of schedule.
regra (não inclua a regra negativa). Desta vez, você deve ver as mensagens de e-mail e SMS retornadas conforme o esperado.Alguns pontos finais a considerar antes de passar para o próximo exercício:
- É importante ter um humano no loop para rever as mensagens geradas. Neste exemplo, as finalizações do Azure OpenAI retornam mensagens de email e SMS sugeridas, mas o usuário pode substituí-las antes de serem enviadas. Se você planeja automatizar e-mails, ter algum tipo de processo de revisão humana para garantir que as mensagens aprovadas estejam sendo enviadas é importante. Veja a IA como sendo um copiloto, não um piloto automático.
- As finalizaçõ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 que são retornadas. Considere o uso do fluxo de prompt para criar uma solução abrangente que simplifique a criação de protótipos, a experimentação, a iteração e a implantação de aplicativos de IA. Convide outras partes interessadas do projeto para revisar as conclusões também.
- Talvez seja necessário incluir o código de 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.
AI: Azure OpenAI em seus dados
A integração do Processamento de Linguagem Natural (NLP) do Azure OpenAI e os recursos de conclusão oferecem um potencial significativo para melhorar a produtividade do usuário. Ao aproveitar prompts e regras apropriados, um assistente de IA pode gerar de forma eficiente várias formas de comunicação, como mensagens de e-mail, mensagens SMS e muito mais. Essa funcionalidade leva a uma maior eficiência do usuário e fluxos de trabalho simplificados.
Embora esse recurso seja bastante poderoso por si só, pode haver casos em que os usuários precisem gerar finalizações com base nos dados personalizados da sua empresa. Por exemplo, você pode ter uma coleção de manuais de produtos que podem ser difíceis para os usuários navegarem quando estão ajudando os clientes com problemas de instalação. Como alternativa, você pode manter um conjunto abrangente de Perguntas Frequentes (FAQs) relacionadas aos benefícios de saúde que podem ser difíceis para os usuários lerem e obterem as respostas de que precisam. Nesses casos e em muitos outros, o Serviço OpenAI do Azure permite que você aproveite seus próprios dados para gerar conclusão, garantindo uma resposta mais personalizada e contextualmente precisa às perguntas dos usuários.
Aqui está uma visão geral rápida de como o recurso "traga seus próprios dados" funciona na documentação do Azure OpenAI.
Nota
Um dos principais recursos do Azure OpenAI em seus dados é sua capacidade de recuperar e utilizar dados de uma forma que aprimora a saída do modelo. O Azure OpenAI em seus dados, juntamente com o Azure AI Search, determina quais dados recuperar da fonte de dados designada com base na entrada do usuário e no histórico de conversas fornecido. Esses dados são então aumentados e reenviados como um prompt para o modelo OpenAI, com as informações recuperadas sendo anexadas ao prompt original. Embora os dados recuperados estejam sendo anexados ao prompt, a entrada resultante ainda é processada pelo modelo como qualquer outro prompt. Depois que os dados forem recuperados e o prompt for enviado ao modelo, o modelo usará essas informações para fornecer uma conclusão.
Neste exercício, irá:
- Crie uma fonte de dados personalizada usando o Azure AI Studio.
- Implante um modelo de incorporação usando o Azure AI Studio.
- Carregue documentos personalizados.
- Inicie uma sessão de bate-papo no playground de bate-papo para experimentar gerar conclusões com base em seus próprios dados.
- Explore o código que usa o Azure AI Search e o Azure OpenAI para gerar conclusões com base em seus próprios dados.
Vamos começar implantando um modelo de incorporação e adicionando uma fonte de dados personalizada no Azure AI Studio.
Adicionando uma fonte de dados personalizada ao Azure AI Studio
Navegue até o Azure OpenAI Studio e entre com credenciais que têm acesso ao seu recurso do Azure OpenAI.
Selecione Implantações no menu de navegação.
Selecione Selecionar Implantar modelo -->Implantar modelo base na barra de ferramentas.
Selecione o modelo text-embedding-ada-002 na lista de modelos e selecione Confirmar.
Selecione as seguintes opções:
- Nome da implantação: text-embedding-ada-002
- Versão do modelo: Padrão
- Tipo de implantação: Padrão
- Defina o valor de Limite de Taxa de Tokens por Minuto (milhares) para 120K
- Filtro de conteúdo: DefaultV2
- Ativar cotação dinâmica: Ativado
Selecione o botão Implantar .
Depois que o modelo for criado, selecione Início no menu de navegação para ir para a tela de boas-vindas.
Localize o bloco Traga seus próprios dados na tela de boas-vindas e selecione Experimente agora.
Selecione Adicionar seus dados seguido de Adicionar uma fonte de dados.
Na lista suspensa Selecionar fonte de dados, selecione Carregar arquivos.
Na lista suspensa Selecionar recurso de armazenamento de Blob do Azure, selecione Criar um novo recurso de armazenamento de Blob do Azure.
Selecione sua assinatura do Azure na lista suspensa Assinatura .
Na lista suspensa Selecionar recurso de armazenamento de Blob do Azure, selecione Criar um novo recurso de armazenamento de Blob do Azure.
Isso o levará ao portal do Azure, onde poderá executar as seguintes tarefas:
- Insira um nome exclusivo para a conta de armazenamento, como byodstorage[Seu sobrenome].
- Selecione uma região próxima da sua localização.
- Selecione Revisão seguida de Criar.
Depois que o recurso de armazenamento de blob for criado, volte para a caixa de diálogo Azure AI Studio e selecione seu recurso de armazenamento de blob recém-criado na lista suspensa Selecionar recurso de armazenamento de Blob do Azure. Se você não vê-lo listado, selecione o ícone de atualização ao lado da lista suspensa.
O compartilhamento de recursos entre origens (CORS) precisa ser ativado para que sua conta de armazenamento seja acessada. Selecione Ativar CORS na caixa de diálogo Azure AI Studio.
Na lista suspensa Selecionar recurso do Azure AI Search , selecione Criar um novo recurso do Azure AI Search.
Isso o levará de volta ao portal do Azure, onde poderá executar as seguintes tarefas:
- Insira um nome exclusivo para o recurso AI Search, como byodsearch-[Your Last Name].
- Selecione uma região próxima da sua localização.
- Na seção Nível de preço , selecione Alterar nível de preço e selecione Básico seguido de Selecionar. A camada gratuita não é suportada, então você limpará o recurso AI Search no final deste tutorial.
- Selecione Revisão seguida de Criar.
Depois que o recurso AI Search for criado, vá para a página Visão geral do recurso e copie o valor Url para um arquivo local.
Selecione Configurações -->Teclas no menu de navegação.
Na página Controle de acesso à API, selecione Ambos para permitir que o serviço seja acessado usando a Identidade Gerenciada ou uma chave. Selecione Sim quando solicitado.
Nota
Embora usemos uma chave de API neste exercício, uma vez que adicionar atribuições de função pode levar até 10 minutos, com um pouco de esforço adicional você pode habilitar uma identidade gerenciada atribuída ao sistema para acessar o serviço com mais segurança.
Selecione Teclas no menu de navegação esquerdo e copie o valor da chave de administração primária para um arquivo local. Você precisará da URL e dos valores-chave mais adiante no exercício.
Selecione Configurações -->Classificação semântica no menu de navegação e verifique se Gratuito está selecionado.
Nota
Para verificar se o classificador semântico está disponível em uma região específica, verifique a página Produtos disponíveis por região no site do Azure para ver se sua região está listada.
Volte para a caixa de diálogo Adicionar Dados do Azure AI Studio e selecione seu recurso de pesquisa recém-criado na lista suspensa Selecionar recurso de Pesquisa do Azure AI. Se você não vê-lo listado, selecione o ícone de atualização ao lado da lista suspensa.
Insira um valor de byod-search-index para o valor Enter the index name .
Marque a caixa de seleção Adicionar pesquisa vetorial a este recurso de pesquisa.
Na lista suspensa Selecione um modelo de incorporação, selecione o modelo text-embedding-ada-002 criado anteriormente.
Na caixa de diálogo Carregar ficheiros, selecione Procurar um ficheiro.
Navegue até a pasta de documentos do cliente do projeto (localizada na raiz do projeto) e selecione os seguintes arquivos:
- Relógio A102 Instalação Instructions.docx
- FAQs.docx da empresa
Nota
Atualmente, esse recurso suporta os 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 blob 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.
Nota
Esta opção fornece suporte para pesquisa de palavras-chave e vetoriais. Uma vez que os resultados são retornados, um processo de classificação secundária é aplicado ao conjunto de resultados usando modelos de aprendizagem profunda que melhoram a relevância da pesquisa para o usuário. Para saber mais sobre a pesquisa semântica, consulte a Pesquisa semântica na documentação do Azure AI Search .
Verifique se o valor Selecionar um tamanho está definido como 1024.
Selecione Seguinte.
Para o tipo de autenticação de recurso do Azure, selecione Chave de API. Saiba mais sobre como selecionar o tipo de autenticação correto na documentação de autenticação do Azure AI Search.
Selecione Seguinte.
Reveja os detalhes e selecione Guardar e fechar.
Agora que seus dados personalizados foram carregados, os dados serão indexados e estarão disponíveis para uso no Chat playground. Este processo poderá demorar alguns minutos. Depois de concluído, continue para a próxima seção.
Usando sua fonte de dados personalizada no Chat Playground
Localize a seção Sessão de bate-papo da página no Azure OpenAI Studio e insira a seguinte consulta de usuário:
What safety rules are required to install a clock?
Depois de enviar a consulta do usuário, você verá um resultado semelhante ao seguinte exibido:
Expanda a seção 1 referências na resposta do bate-papo e observe que o arquivo de Instructions.docx de instalação do Clock A102 está listado e que você pode selecioná-lo para exibir o documento.
Digite a seguinte mensagem de usuário:
What should I do to mount the clock on the wall?
Você verá um resultado semelhante ao seguinte exibido:
Agora vamos experimentar o documento de perguntas frequentes da empresa. Insira o seguinte texto no campo Consulta do usuário:
What is the company's policy on vacation time?
Você deve ver que nenhuma informação foi encontrada para essa solicitação.
Insira o seguinte texto no campo Consulta do usuário:
How should I handle refund requests?
Você verá um resultado semelhante ao seguinte exibido:
Expanda a seção 1 referências na resposta do bate-papo e observe que o arquivo de FAQs.docx da empresa está listado e que você pode selecioná-lo para visualizar o documento.
Selecione Exibir código na barra de ferramentas do Chat playground.
Observe que você pode alternar entre idiomas diferentes, exibir o ponto de extremidade e acessar a chave do ponto de extremidade. Feche a janela de diálogo Código de exemplo.
Ative a alternância Mostrar JSON bruto acima das mensagens de chat. Observe que a sessão de bate-papo começa com uma mensagem semelhante à seguinte:
{ "role": "system", "content": "You are an AI assistant that helps people find information." }
Agora que você criou uma fonte de dados personalizada e a experimentou no Chat playground, vamos ver como você pode usá-la no aplicativo do projeto.
Usando o recurso Traga seus próprios dados no aplicativo
Volte para o projeto no VS Code e abra o arquivo .env . Atualize os valores a seguir com o endpoint, a chave e o nome do índice do AI Services. Você copiou o ponto de extremidade e a chave para um arquivo local anteriormente neste exercício.
AZURE_AI_SEARCH_ENDPOINT=<AI_SERVICES_ENDPOINT_VALUE> AZURE_AI_SEARCH_KEY=<AI_SERVICES_KEY_VALUE> AZURE_AI_SEARCH_INDEX=byod-search-index
Em um exercício anterior, você iniciou o banco de dados, as APIs e o aplicativo. Você também atualizou o
.env
arquivo. Se você não concluiu essas etapas, siga as instruções no final do exercício anterior antes de continuar.Depois que o aplicativo for carregado no navegador, selecione o ícone Ajuda do bate-papo no canto superior direito do aplicativo.
O seguinte texto deve aparecer na caixa de diálogo do chat:
How should I handle a company refund request?
Selecione o botão Obter Ajuda . Você deve ver os resultados retornados do documento do FAQs.docx da Empresa que você carregou anteriormente no Azure OpenAI Studio. Se você quiser ler o documento, você pode encontrá-lo na pasta de documentos do cliente na raiz do projeto.
Altere o texto para o seguinte e selecione o botão Obter Ajuda :
What safety rules are required to install a clock?
Você deve ver os resultados retornados do documento do Instructions.docx de Instalação do Relógio A102 que você carregou anteriormente no Azure OpenAI Studio. Este documento também está disponível na pasta de documentos do cliente na raiz do projeto.
Explorando o código
Gorjeta
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Volte para o código-fonte do projeto no Visual Studio Code.
Abra o arquivo server/apiRoutes.ts e localize a
completeBYOD
rota. Essa API é chamada quando o botão Obter Ajuda é selecionado na caixa de diálogo Ajuda do Chat. Ele recupera o prompt do usuário do corpo da solicitação e o passa para acompleteBYOD()
função no arquivo server/openAI.ts . Os resultados são então devolvidos ao cliente.router.post('/completeBYOD', async (req, res) => { const { prompt } = req.body; if (!prompt) { return res.status(400).json({ status: false, error: 'The prompt parameter must be provided.' }); } let result; try { // Call OpenAI to get custom "bring your own data" completion result = await completeBYOD(prompt); } catch (e: unknown) { console.error('Error parsing JSON:', e); } res.json(result); });
Abra o arquivo server/openAI.ts e localize a
completeBYOD()
função.async function completeBYOD(userPrompt: string): Promise<string> { const systemPrompt = 'You are an AI assistant that helps people find information in documents.'; return await callOpenAI(systemPrompt, userPrompt, 0, true); }
Esta função tem as seguintes características:
- O
userPrompt
parâmetro contém as informações que o usuário digitou na caixa de diálogo de ajuda do chat. - a
systemPrompt
variável define que 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 incluir na resposta. O usuário precisa de respostas consistentes (menos criativas) neste caso, então o valor é definido como 0.useBYOD
- Um valor booleano que indica se deve ou não usar a Pesquisa de IA junto com o Azure OpenAI. Neste caso, está configurado para que atrue
funcionalidade AI Search seja usada.
- O
A
callOpenAI()
função aceita umuseBYOD
parâmetro que é usado para determinar qual função OpenAI chamar. Neste caso, ele defineuseBYOD
paratrue
que agetAzureOpenAIBYODCompletion()
função será chamada.function callOpenAI(systemPrompt: string, userPrompt: string, temperature = 0, useBYOD = false) { const isAzureOpenAI = OPENAI_API_KEY && OPENAI_ENDPOINT && OPENAI_MODEL; if (isAzureOpenAI) { if (useBYOD) { return getAzureOpenAIBYODCompletion(systemPrompt, userPrompt, temperature); } return getAzureOpenAICompletion(systemPrompt, userPrompt, temperature); } return getOpenAICompletion(systemPrompt, userPrompt, temperature); }
Localize a
getAzureOpenAIBYODCompletion()
função no servidor/openAI.ts. É bastante semelhante àgetAzureOpenAICompletion()
função que você examinou anteriormente, mas é mostrada como uma função separada para destacar algumas diferenças importantes que são exclusivas para o cenário "Azure OpenAI em seus dados" disponível no Azure OpenAI.async function getAzureOpenAIBYODCompletion(systemPrompt: string, userPrompt: string, temperature: number): Promise<string> { const dataSources = [ { type: 'azure_search', parameters: { authentication: { type: 'api_key', key: AZURE_AI_SEARCH_KEY }, endpoint: AZURE_AI_SEARCH_ENDPOINT, index_name: AZURE_AI_SEARCH_INDEX } } ]; const completion = await createAzureOpenAICompletion(systemPrompt, userPrompt, temperature, dataSources) as AzureOpenAIYourDataResponse; console.log('Azure OpenAI Add Your Own Data Output: \n', completion.choices[0]?.message); for (let citation of completion.choices[0]?.message?.context?.citations ?? []) { console.log('Citation Path:', citation.filepath); } return completion.choices[0]?.message?.content?.trim() ?? ''; }
Observe a seguinte funcionalidade na
getAzureOpenAIBYODCompletion()
função:- É criada uma
dataSources
propriedade que contém os valores do recursokey
AI Search ,endpoint
eindex_name
que foram adicionados ao.env
arquivo anteriormente neste exercício - A
createAzureOpenAICompletion()
função é chamada com ossystemPrompt
valores ,userPrompt
,temperature
, edataSources
. Essa função é usada para chamar a API OpenAI do Azure e retornar os resultados. - Assim que a resposta é retornada, as citações do documento são registradas no console. O conteúdo da mensagem de conclusão é então devolvido ao chamador.
- É criada uma
Alguns pontos finais a considerar antes de passar para o próximo exercício:
- O aplicativo de exemplo usa um único índice no Azure AI Search. Você pode usar vários índices e fontes de dados com o Azure OpenAI. A
dataSources
propriedade na função pode ser atualizada para incluir várias fontes de dados,getAzureOpenAIBYODCompletion()
conforme necessário. - A segurança deve ser cuidadosamente avaliada com este tipo de cenário. Os usuários não devem ser capazes de fazer perguntas e obter resultados de documentos que eles não são capazes de acessar.
- O aplicativo de exemplo usa um único índice no Azure AI Search. Você pode usar vários índices e fontes de dados com o Azure OpenAI. A
Agora que você aprendeu sobre o Azure OpenAI, prompts, finalizações e como você pode usar seus próprios dados, vamos para o próximo exercício para saber como os recursos de comunicação podem ser usados para aprimorar o aplicativo. Se quiser saber mais sobre o Azure OpenAI, veja o conteúdo de formação 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 Azure OpenAI em sua documentação de dados .
Comunicação: Criando um recurso dos Serviços de Comunicação do Azure
Uma comunicação eficaz é essencial para o sucesso de aplicativos de negócios personalizados. Usando os Serviços de Comunicação do Azure (ACS), você pode adicionar recursos como chamadas telefônicas, bate-papo ao vivo, chamadas de áudio/vídeo e mensagens de email e SMS aos seus aplicativos. Anteriormente, você aprendeu como o Azure OpenAI pode gerar conclusões para mensagens de email e SMS. Agora, você aprenderá como enviar as mensagens. Juntos, o ACS e o OpenAI podem aprimorar seus aplicativos simplificando a comunicação, melhorando as interações e aumentando a produtividade dos negócios.
Neste exercício, irá:
- Crie um recurso dos Serviços de Comunicação do Azure (ACS).
- Adicione um número de telefone gratuito com recursos de chamadas e SMS.
- Conecte um domínio de e-mail.
- Atualize o arquivo .env do projeto com valores do seu recurso ACS.
Criar um recurso dos Serviços de Comunicação do Azure
Visite o portal do Azure em seu navegador e entre se ainda não o fez.
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 a subscrição do Azure.
- Selecione o grupo de recursos a ser usado (crie um novo, se não existir).
- Insira um nome de recurso ACS. Tem de ser um valor exclusivo.
- Selecione um local de dados.
Selecione Rever + Criar seguido de Criar.
Você criou com êxito um novo recurso dos Serviços de Comunicação do Azure! Em seguida, você habilitará os recursos de chamadas telefônicas e SMS. Você também conectará um domínio de e-mail ao recurso.
Habilite os recursos de chamadas telefônicas e SMS
Adicione um número de telefone e verifique se o número de telefone tem recursos de chamada ativados. Irá utilizar este número de telefone para ligar para um telefone a partir da aplicação.
Selecione Telefonia e SMS -->Números de telefone no menu Recurso.
Selecione + Obter na barra de ferramentas (ou selecione o botão Obter um número ) e insira as seguintes informações:
- País ou região:
United States
- Tipo de número:
Toll-free
Nota
É necessário um cartão de crédito na sua subscrição do Azure para criar o número gratuito. Se você não tiver um cartão registrado, sinta-se à vontade para pular 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 e-mail. Você ainda pode usar o aplicativo, mas não poderá ligar para um número de telefone.
- Número: Selecione Adicionar ao carrinho para um dos números de telefone listados.
- País ou região:
Selecione Seguinte, reveja os detalhes do número de telefone e selecione Comprar agora.
Nota
A verificação por SMS para números gratuitos é agora obrigatória nos Estados Unidos e no Canadá. Para habilitar as mensagens SMS, você deve enviar a verificação após a compra do número de telefone. Embora este tutorial não passe por esse processo, você pode selecionar Telefonia e SMS -->Documentos regulatórios no menu de recursos e adicionar a documentação de validação necessária.
Depois que o número de telefone for criado, selecione-o para acessar o painel Recursos . Certifique-se de que os seguintes valores estão definidos (eles devem ser definidos por padrão):
- Na seção Chamadas, selecione
Make calls
. - Na seção SMS, selecione
Send and receive SMS
. - Selecione Guardar.
- Na seção Chamadas, selecione
Copie o valor do número de telefone em um arquivo para uso posterior. O número de telefone deve seguir este padrão geral:
+12345678900
.
Conectar um domínio de e-mail
Execute as seguintes tarefas para criar um domínio de email conectado para seu recurso ACS para que você possa enviar email. Isso será usado para enviar e-mails do aplicativo.
- Selecione Email -->Domínios no menu Recurso.
- Selecione Conectar domínio na barra de ferramentas.
- Selecione o seu grupo Subscrição e Recursos.
- Na lista suspensa Serviço de e-mail, selecione
Add an email service
. - Dê ao serviço de e-mail um nome como
acs-demo-email-service
. - Selecione Rever + criar seguido de Criar.
- Quando 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 momentos para ser implantado), selecione-o.
- Quando estiver na tela AzureManagedDomain, selecione Serviços de email -->MailFrom addresses no menu Recurso.
- Copie o valor MailFrom para um arquivo. Você o usará mais tarde à medida que atualizar o arquivo .env .
- Volte para o recurso dos Serviços de Comunicação do Azure e selecione Email -->Domínios no menu de recursos.
- Selecione
Add domain
e insira oMailFrom
valor da etapa anterior (certifique-se de selecionar a assinatura, o grupo de recursos e o serviço de email corretos). Selecione o botãoConnect
.
Atualizar o .env
arquivo
Agora que seu número de telefone ACS (com chamadas e SMS habilitados) e domínio de e-mail 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 oACS_PHONE_NUMBER
seu número gratuito ao valor.ACS_EMAIL_ADDRESS
: Atribua o valor do seu endereço de e-mail "MailTo".CUSTOMER_EMAIL_ADDRESS
: atribua um endereço de e-mail para o qual você gostaria que o e-mail 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 e-mail pessoal.CUSTOMER_PHONE_NUMBER
: Você precisará fornecer um número de telefone baseado nos Estados Unidos (a partir de hoje) devido à verificação adicional que é necessária em outros países para enviar mensagens SMS. Se não tiver um número baseado nos EUA, pode deixá-lo vazio.
Iniciar/reiniciar os servidores de aplicativos e API
Execute uma das seguintes etapas com base nos exercícios concluídos até este ponto:
Se você iniciou o banco de dados, o servidor de API e o servidor Web em um exercício anterior, precisará parar o servidor de API e o servidor Web e reiniciá-los para pegar as alterações do arquivo .env . Você pode deixar o banco de dados em execução.
Localize as janelas do terminal que executam o servidor API e o servidor Web e pressione CTRL + C para pará-las. Inicie-os novamente digitando
npm start
em cada janela do terminal e pressionando Enter. Continue para o próximo exercício.Se você ainda não iniciou o banco de dados, o servidor de API e o servidor Web, conclua as seguintes etapas:
Nas etapas a seguir, você criará três janelas de terminal no Visual Studio Code.
Clique com o botão direito do mouse no arquivo .env na lista de arquivos de código do Visual Studio e selecione Abrir no Terminal integrado. Certifique-se de que seu 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 o Docker Desktop, o Podman, o nerdctl ou outro tempo de execução de contêiner instalado, execute o seguinte comando na janela do terminal:
Subsistema Mac, Linux ou Windows para Linux (WSL):
[docker | podman | nerdctl] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v $(pwd)/data:/var/lib/postgresql/data -p 5432:5432 postgres
Windows com PowerShell:
[docker | podman] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v ${PWD}/data:/var/lib/postgresql/data -p 5432:5432 postgres
Quando o contêiner de banco de dados for iniciado, pressione o + ícone na barra de ferramentas Terminal de código do Visual Studio para criar uma segunda janela de terminal.
cd
na pasta server/typescript e execute os seguintes comandos para instalar as dependências e iniciar o servidor API.npm install
npm start
Pressione o + ícone novamente na barra de ferramentas Terminal de código do Visual Studio para criar uma terceira janela do terminal.
cd
na pasta cliente e execute os seguintes comandos para instalar as dependências e iniciar o servidor Web.npm install
npm start
Um navegador será iniciado e você será direcionado para http://localhost:4200.
Comunicação: Fazer uma chamada telefónica
A integração dos recursos de chamada telefônica dos Serviços de Comunicação do Azure em um aplicativo personalizado de Linha de Negócios (LOB) oferece vários benefícios importantes para as empresas e seus usuários:
- Permite uma comunicação contínua e em tempo real entre funcionários, clientes e parceiros, diretamente a partir do aplicativo LOB, eliminando a necessidade de alternar entre várias plataformas ou dispositivos.
- Melhora a experiência do usuário e melhora a eficiência operacional geral.
- Facilita a resolução rápida de problemas, pois os usuários podem se conectar rapidamente com equipes de suporte relevantes ou especialistas no assunto de forma rápida e fácil.
Neste exercício, irá:
- 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 Azure Communication Services (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>
Certifique-se de ter concluído o exercício anterior antes de continuar.
Volte para o navegador (http://localhost:4200), localize a grade de dados e selecione Entrar em contato com o cliente seguido por Ligar para o cliente na primeira linha.
Um componente de chamada telefônica será adicionado ao cabeçalho. Introduza o seu número de telefone para o qual pretende ligar (certifique-se de que começa com + e inclui o código do país) e selecione Chamar. Ser-lhe-á pedido que permita o acesso ao seu microfone.
Selecione Desligar para encerrar a chamada. Selecione Fechar para fechar o componente de chamada telefônica.
Explorando o código de chamada telefônica
Gorjeta
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Abra o arquivo customers-list.component.ts . O caminho completo para o arquivo é client/src/app/customers-list/customers-list.component.ts.
Observe que
openCallDialog()
envia umaCustomerCall
mensagem e o número de telefone do cliente usando um barramento de eventos.openCallDialog(data: Phone) { this.eventBus.emit({ name: Events.CustomerCall, value: data }); }
Nota
O código do barramento de eventos pode ser encontrado no arquivo eventbus.service.ts se você estiver interessado em explorá-lo mais. O caminho completo para o arquivo é client/src/app/core/eventbus.service.ts.
A função do
ngOnInit()
componente de cabeçalho assina oCustomerCall
evento enviado pelo barramento de eventos e exibe o componente de chamada telefônica. Você pode encontrar esse código em header.component.ts.ngOnInit() { this.subscription.add( this.eventBus.on(Events.CustomerCall, (data: Phone) => { this.callVisible = true; // Show phone call component this.callData = data; // Set phone number to call }) ); }
Abra phone-call.component.ts. Reserve um momento para expor o código. O caminho completo para o arquivo é client/src/app/phone-call/phone-call.component.ts. Observe os seguintes recursos principais:
- Recupera um token de acesso dos Serviços de Comunicação do Azure chamando a
acsService.getAcsToken()
função emngOnInit()
; - Adiciona um "discador telefônico" à 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 dos Serviços de Comunicação do Azure chamando a
Antes de examinar o código que faz a chamada telefônica, vamos examinar como o token de acesso 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); }) ); } }
Esta 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 uso dos
CallAgent
CallClient
objetos eAzureCommunicationTokenCredential
. Mais tarde, você verá queCallAgent
é usado para iniciar e terminar 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 o userId e o token de acesso e o retorna ao cliente. Ele pode ser encontrado no arquivo server/typescript/acs.ts .import { CommunicationIdentityClient } from '@azure/communication-identity'; const connectionString = process.env.ACS_CONNECTION_STRING as string; async function createACSToken() { if (!connectionString) return { userId: '', token: '' }; const tokenClient = new CommunicationIdentityClient(connectionString); const { user, token } = await tokenClient.createUserAndToken(["voip"]); return { userId: user.communicationUserId, token }; }
Esta 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 e
CommunicationIdentityClient
passa oconnectionString
valor para ela. - Cria um novo usuário e token usando
tokenClient.createUserAndToken()
com o escopo "voip". - Retorna um objeto que contém os
userId
valores etoken
.
- Verifica se um valor ACS
Agora que você já viu como o userId e o token são recuperados, volte e
phone-call.component.ts
localize astartCall()
função.Esta 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; // Adding event handlers to monitor call state this.call?.on('stateChanged', () => { console.log('Call state changed: ', this.call?.state); if (this.call?.state === 'Disconnected') { console.log('Call ended. Reason: ', this.call.callEndReason); this.inCall = false; } }); }
A
endCall()
função é chamada quando 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 rever 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.createUserAndToken()
função. - O token é usado para criar um
CallClient
eCallAgent
objeto. - O
CallAgent
objeto é usado para iniciar e terminar 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 os Serviços de Comunicação do Azure para enviar mensagens de email e SMS.
Comunicação: Envio de e-mail e mensagens SMS
Além das chamadas telefónicas, os Serviços de Comunicação do Azure também podem enviar mensagens de correio eletrónico e SMS. Isso pode ser útil quando você deseja enviar uma mensagem para um cliente ou outro usuário diretamente do aplicativo.
Neste exercício, irá:
- Explore como as mensagens de e-mail e SMS podem ser enviadas a partir da aplicação.
- Percorra o código para saber como a funcionalidade de e-mail e SMS é implementada.
Usando os recursos de e-mail e SMS
Em um exercício anterior, você criou um recurso dos 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>
Certifique-se de ter concluído o exercício antes de continuar.
Volte para o navegador (http://localhost:4200) e selecione Entrar em contato com o cliente seguido de E-mail/SMS Cliente na primeira linha.
Selecione a guia E-mail/SMS e execute as seguintes tarefas:
- Insira um assunto e corpo do e-mail e selecione o botão Enviar e-mail.
- Insira uma mensagem SMS e selecione o botão Enviar SMS .
Nota
A verificação por SMS para números gratuitos é agora obrigatória nos Estados Unidos e no Canadá. Para habilitar as mensagens SMS, você deve enviar a verificação após a compra do número de telefone. Embora este tutorial não passe por esse processo, você pode selecionar Telefonia e SMS -->Documentos Regulatórios do recurso Serviços de Comunicação do Azure no portal do Azure e adicionar a documentação de validação necessária.
Verifique se recebeu o e-mail e as mensagens SMS. A funcionalidade SMS só funcionará se você enviar os documentos regulamentares mencionados na nota anterior. Como lembrete, a mensagem de e-mail será enviada para o valor definido para
CUSTOMER_EMAIL_ADDRESS
e a mensagem SMS será enviada para o valor definido paraCUSTOMER_PHONE_NUMBER
o arquivo .env . Se você não foi capaz de fornecer um número de telefone baseado nos Estados Unidos para usar para mensagens SMS, você pode pular essa etapa.Nota
Se não vir a mensagem de e-mail na sua caixa de entrada para o endereço que definiu
CUSTOMER_EMAIL_ADDRESS
no ficheiro .env, verifique a sua pasta de spam.
Explorando o código de e-mail
Gorjeta
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Abra o arquivo customers-list.component.ts . O caminho completo para o arquivo é client/src/app/customers-list/customers-list.component.ts.
Quando você selecionou Entrar em contato com o cliente seguido de E-mail/SMS Cliente na grade de dados, o
customer-list
componente exibiu uma caixa de diálogo. Isso é tratado pelaopenEmailSmsDialog()
função no arquivo customer-list.component.ts .openEmailSmsDialog(data: any) { if (data.phone && data.email) { // Create the data for the dialog let dialogData: EmailSmsDialogData = { prompt: '', title: `Contact ${data.company}`, company: data.company, customerName: data.first_name + ' ' + data.last_name, customerEmailAddress: data.email, customerPhoneNumber: data.phone } // Open the dialog const dialogRef = this.dialog.open(EmailSmsDialogComponent, { data: dialogData }); // Subscribe to the dialog afterClosed observable to get the dialog result this.subscription.add( dialogRef.afterClosed().subscribe((response: EmailSmsDialogData) => { console.log('SMS dialog result:', response); if (response) { dialogData = response; } }) ); } else { alert('No phone number available.'); } }
A
openEmailSmsDialog()
função executa as seguintes tarefas:- Verifica se o
data
objeto (que representa a linha da grade de dados) contém umaphone
propriedade andemail
. 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. - Inscreve-se no
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 é chamada e o assunto do e-mail, corpo, nome do cliente e endereço de e-mail do cliente sã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. - Subscreve a
sendEmail()
função noacsService
serviço. Esta função retorna um RxJS observável que contém a resposta do serviço do lado do cliente. - Se o e-mail foi enviado com êxito, a
emailSent
propriedade é definida comotrue
.
- Verifica se o sinalizador de
Para fornecer melhor encapsulamento e reutilização de código, serviços do lado do cliente, como acs.service.ts são usados em todo o aplicativo. Isso permite que todas as funcionalidades do ACS sejam consolidadas em um único local.
Abra acs.service.ts e localize a
sendEmail()
função. O caminho completo para o arquivo é client/src/app/core/acs.service.ts.sendEmail(subject: string, message: string, customerName: string, customerEmailAddress: string) : Observable<EmailSmsResponse> { return this.http.post<EmailSmsResponse>(this.apiUrl + 'sendEmail', { subject, message, customerName, customerEmailAddress }) .pipe( catchError(this.handleError) ); }
A
sendEmail()
função emAcsService
executa as seguintes tarefas:- Chama a
http.post()
função e passa o assunto do e-mail, a mensagem, o nome do cliente e o endereço de e-mail do cliente para ela. Ahttp.post()
função retorna um RxJS observável que contém a resposta da chamada de API. - Manipula quaisquer erros retornados
http.post()
pela função usando o operador RxJScatchError
.
- Chama a
Agora vamos examinar como o aplicativo interage com o recurso de e-mail ACS. Abra o arquivo acs.ts e localize a
sendEmail()
função. O caminho completo para o arquivo é server/typescript/acs.ts.A
sendEmail()
função executa as seguintes tarefas:Cria um novo
EmailClient
objeto e passa a cadeia de conexão ACS para ele (esse valor é recuperado daACS_CONNECTION_STRING
variável de ambiente).const emailClient = new EmailClient(connectionString);
Cria um novo
EmailMessage
objeto e passa as informações do remetente, assunto, mensagem e destinatário.const msgObject: EmailMessage = { senderAddress: process.env.ACS_EMAIL_ADDRESS as string, content: { subject: subject, plainText: message, }, recipients: { to: [ { address: customerEmailAddress, displayName: customerName, }, ], }, };
Envia o e-mail usando a
emailClient.beginSend()
função e retorna a resposta. Embora a função esteja enviando apenas para um destinatário neste exemplo, abeginSend()
função também pode ser usada para enviar para vários destinatários.const poller = await emailClient.beginSend(msgObject);
Aguarda que o
poller
objeto sinalize que está feito e envia a resposta para o chamador.
Explorando o código SMS
Volte ao ficheiro email-sms-dialog.component.ts que 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 verdade, aacsService.SendSms()
função é chamada e a mensagem SMS e o número de telefone do cliente sã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. - Subscreve a
sendSms()
função noacsService
serviço. Esta 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 de API. - Manipula quaisquer erros retornados
http.post()
pela função usando o operador RxJScatchError
.
- Chama a
Finalmente, vamos examinar como o aplicativo interage com o recurso ACS SMS. Abra o arquivo acs.ts . O caminho completo para o arquivo é server/typescript/acs.ts e localize a
sendSms()
função.A
sendSms()
função executa as seguintes tarefas:Cria um novo
SmsClient
objeto e passa a cadeia de conexão ACS para ele (esse valor é recuperado daACS_CONNECTION_STRING
variável de ambiente).const smsClient = new SmsClient(connectionString);
Chama a
smsClient.send()
função e passa o número de telefone ACS (from
), número de telefone do cliente (to
) e mensagem SMS:const sendResults = await smsClient.send({ from: process.env.ACS_PHONE_NUMBER as string, to: [customerPhoneNumber], message: message }); return sendResults;
Retorna a resposta ao chamador.
Você pode saber mais sobre a funcionalidade de e-mail e SMS do ACS nos seguintes artigos:
Antes de passar para o próximo exercício, vamos rever os principais conceitos abordados neste exercício:
- O arquivo acs.service.ts encapsula a funcionalidade de e-mail e SMS ACS usada pelo aplicativo do lado do cliente. Ele lida com as chamadas de API para o servidor e retorna a resposta para o chamador.
- A API do lado do servidor usa o ACS e
SmsClient
objetos para enviar mensagens deEmailClient
e-mail e SMS.
Agora que você já aprendeu como as mensagens de e-mail e SMS podem ser enviadas, vamos mudar nosso foco para a integração de dados organizacionais no aplicativo.
Dados organizacionais: Criando um registro de aplicativo Microsoft Entra ID
Melhore a produtividade do usuário integrando dados organizacionais (e-mails, arquivos, bate-papos e eventos de calendário) diretamente em seus aplicativos personalizados. Usando as APIs do Microsoft Graph e o Microsoft Entra ID, você pode recuperar e exibir facilmente dados relevantes em seus aplicativos, reduzindo a necessidade de os usuários alternarem de contexto. Seja fazendo referência a um e-mail enviado a um cliente, revisando uma mensagem do Teams ou acessando um arquivo, os usuários podem encontrar rapidamente as informações de que precisam sem sair do seu aplicativo, simplificando o processo de tomada de decisões.
Neste exercício, irá:
- Crie um registro de aplicativo Microsoft Entra ID para que o Microsoft Graph possa acessar dados organizacionais e trazê-los para o aplicativo.
- Localize
team
echannel
Ids do Microsoft Teams que são necessários para enviar mensagens de chat para um canal específico. - Atualize o arquivo .env do projeto com valores do registro do aplicativo Microsoft Entra ID.
Criar um registro de aplicativo Microsoft Entra ID
Vá para o portal do Azure e selecione Microsoft Entra ID.
Selecione Gerenciar -->Registros de aplicativos seguido de + 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 suportados: Contas em qualquer diretório organizacional (Qualquer locatário do Microsoft Entra ID - Multilocatário)
- URI de redirecionamento:
- Selecione Aplicativo de página única (SPA) e insira
http://localhost:4200
no campo Redirecionar URI .
- Selecione Aplicativo de página única (SPA) e insira
- Selecione Registrar para criar o registro do aplicativo.
Selecione Visão geral no menu de recursos e copie o valor para a
Application (client) ID
área de transferência.
Atualizar o arquivo .env do projeto
Abra o arquivo .env 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 (isso é mencionado nos pré-reqs do tutorial).
Depois de iniciar sessão, expanda uma equipa e encontre um canal para o qual pretende enviar mensagens a partir da aplicação. Por exemplo, você pode selecionar a equipe da Empresa e o canal Geral (ou qualquer equipe/canal que você gostaria de usar).
No cabeçalho da equipe, clique nos três pontos (...) e selecione Obter link para a equipe.
No link que aparece na janela pop-up, o ID da equipe é a sequência de letras e números após
team/
. Por exemplo, no link "https://teams.microsoft.com/l/team/19%3ae9b9.../", o ID da equipe é 19%3ae9b9... até o seguinte/
personagem.Copie o ID da equipe e atribua-o no
TEAM_ID
arquivo .env.No cabeçalho do canal, clique nos três pontos (...) e selecione Obter link para o canal.
No link que aparece na janela pop-up, o ID do canal é a sequência de letras e números após
channel/
. Por exemplo, no link "https://teams.microsoft.com/l/channel/19%3aQK02.../", o ID do canal é 19%3aQK02... até o seguinte/
personagem.Copie o ID do canal e atribua-o no
CHANNEL_ID
arquivo .env.Salve o arquivo env antes de continuar.
Iniciar/reiniciar os servidores de aplicativos e API
Execute uma das seguintes etapas com base nos exercícios concluídos até este ponto:
Se você iniciou o banco de dados, o servidor de API e o servidor Web em um exercício anterior, precisará parar o servidor de API e o servidor Web e reiniciá-los para pegar as alterações do arquivo .env . Você pode deixar o banco de dados em execução.
Localize as janelas do terminal que executam o servidor API e o servidor Web e pressione CTRL + C para pará-las. Inicie-os novamente digitando
npm start
em cada janela do terminal e pressionando Enter. Continue para o próximo exercício.Se você ainda não iniciou o banco de dados, o servidor de API e o servidor Web, conclua as seguintes etapas:
Nas etapas a seguir, você criará três janelas de terminal no Visual Studio Code.
Clique com o botão direito do mouse no arquivo .env na lista de arquivos de código do Visual Studio e selecione Abrir no Terminal integrado. Certifique-se de que seu 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 o Docker Desktop, o Podman, o nerdctl ou outro tempo de execução de contêiner instalado, execute o seguinte comando na janela do terminal:
Subsistema Mac, Linux ou Windows para Linux (WSL):
[docker | podman | nerdctl] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v $(pwd)/data:/var/lib/postgresql/data -p 5432:5432 postgres
Windows com PowerShell:
[docker | podman] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v ${PWD}/data:/var/lib/postgresql/data -p 5432:5432 postgres
Quando o contêiner de banco de dados for iniciado, pressione o + ícone na barra de ferramentas Terminal de código do Visual Studio para criar uma segunda janela de terminal.
cd
na pasta server/typescript e execute os seguintes comandos para instalar as dependências e iniciar o servidor API.npm install
npm start
Pressione o + ícone novamente na barra de ferramentas Terminal de código do Visual Studio para criar uma terceira janela do terminal.
cd
na pasta cliente e execute os seguintes comandos para instalar as dependências e iniciar o servidor Web.npm install
npm start
Um navegador será iniciado e você será direcionado para http://localhost:4200.
Dados organizacionais: Entrando em um usuário e obtendo um token de acesso
Os usuários precisam se autenticar com o ID do Microsoft Entra para que o Microsoft Graph acesse dados organizacionais. Neste exercício, você verá como o componente do mgt-login
Microsoft Graph Toolkit pode ser usado para autenticar usuários e recuperar um token de acesso. O token de acesso pode ser usado para fazer chamadas para o Microsoft Graph.
Nota
Se você é novo no Microsoft Graph, pode saber mais sobre ele no caminho de aprendizado do Microsoft Graph Fundamentals .
Neste exercício, irá:
- Saiba como associar um aplicativo Microsoft Entra ID ao Microsoft Graph Toolkit 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.
Utilizar a funcionalidade de início de sessão
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
.env
seguintes valores no arquivo (TEAM_ID
eCHANNEL_ID
são opcionais):ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE> TEAM_ID=<TEAMS_TEAM_ID> CHANNEL_ID=<TEAMS_CHANNEL_ID>
Certifique-se de ter concluído o exercício anterior antes de continuar.
Volte para o navegador (http://localhost:4200), selecione Entrar no cabeçalho e entre usando uma conta de usuário administrador do locatário do Microsoft 365 Developer.
Gorjeta
Entre com sua conta de administrador de locatário de desenvolvedor do Microsoft 365. Pode ver outros utilizadores no seu inquilino de programador acedendo ao Centro de administração do Microsoft 365.
Se estiver a iniciar sessão na aplicação pela primeira vez, ser-lhe-á pedido que autorize as permissões solicitadas pela aplicação. 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ê verá o nome do usuário exibido no cabeçalho.
Explorando o código de login
Agora que você entrou, vamos examinar o código usado para entrar no usuário e recuperar um token de acesso e um perfil de usuário. Você aprenderá sobre o componente da Web mgt-login que faz parte do Microsoft Graph Toolkit.
Gorjeta
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Abra o cliente/package.json e observe que os
@microsoft/mgt
pacotes e@microsoft/mgt-components
estão incluídos nas dependências. O@microsoft/mgt
pacote contém recursos do provedor MSAL (Biblioteca de Autenticação da Microsoft) e componentes da Web, como mgt-login e outros, que podem ser usados para entrar em usuários e recuperar e exibir dados organizacionais.Abra client/src/main.ts e observe as
@microsoft/mgt-components
seguintes importações do pacote. Os símbolos importados são usados para registrar os componentes do Microsoft Graph Toolkit que são usados no aplicativo.import { registerMgtLoginComponent, registerMgtSearchResultsComponent, registerMgtPersonComponent, } from '@microsoft/mgt-components';
Desloque-se para a parte inferior do ficheiro e anote o seguinte código:
registerMgtLoginComponent(); registerMgtSearchResultsComponent(); registerMgtPersonComponent();
Esse código registra os
mgt-login
componentes ,mgt-search-results
emgt-person
Web e os habilita para uso no aplicativo.Para usar o componente mgt-login para entrar 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á a seguinte importação e código:import { Msal2Provider, Providers, ProviderState } from '@microsoft/mgt'; init() { if (!this.featureFlags.microsoft365Enabled) return; if (!Providers.globalProvider) { console.log('Initializing Microsoft Graph global provider...'); Providers.globalProvider = new Msal2Provider({ clientId: ENTRAID_CLIENT_ID, scopes: ['User.Read', 'Presence.Read', 'Chat.ReadWrite', 'Calendars.Read', 'ChannelMessage.Read.All', 'ChannelMessage.Send', 'Files.Read.All', 'Mail.Read'] }); } else { console.log('Global provider already initialized'); } }
Esse código cria um novo
Msal2Provider
objeto, passando a ID do cliente Microsoft Entra ID do seu registro de aplicativo e 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 Microsoft Graph Toolkit para recuperar dados do Microsoft Graph.Abra header.component.html no seu editor e localize o componente mgt-login . O caminho completo para o arquivo é client/src/app/header/header.component.html.
@if (this.featureFlags.microsoft365Enabled) { <mgt-login class="mgt-dark" (loginCompleted)="loginCompleted()"></mgt-login> }
O componente mgt-login permite o login do usuário e fornece acesso a um token que é usado com o Microsoft Graph. Após o login bem-sucedido, o evento é acionado, o
loginCompleted
que chama aloginCompleted()
função. Embora mgt-login seja usado dentro de 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 pode se autenticar no Microsoft Entra ID. A bandeira é adicionada para acomodar casos em que os usuários optam por completar apenas os exercícios de IA ou Comunicação dentro do tutorial, em vez de seguir toda a sequência de exercícios.Abra header.component.ts e localize a
loginCompleted
função. Essa função é chamada quando ologinCompleted
evento é emitido e lida com a recuperação do perfil do usuário conectado usandoProviders.globalProvider
o .async loginCompleted() { const me = await Providers.globalProvider.graph.client.api('me').get(); this.userLoggedIn.emit(me); }
Neste exemplo, uma chamada está sendo feita para a API do Microsoft Graph
me
para recuperar o perfil do usuário (me
representa o usuário conectado atual). Athis.userLoggedIn.emit(me)
instrução de código emite um evento do componente para passar os dados de perfil para o componente pai. O componente pai é app.component.ts arquivo neste caso, que é o componente raiz do aplicativo.Para saber mais sobre o componente mgt-login , visite a documentação do Microsoft Graph Toolkit .
Agora que você fez login no aplicativo, vamos ver como os dados organizacionais podem ser recuperados.
Dados organizacionais: recuperando arquivos, bate-papos e enviando mensagens para equipes
No ambiente digital atual, os usuários trabalham com uma ampla gama de dados organizacionais, incluindo e-mails, chats, arquivos, eventos de calendário e muito mais. Isso pode levar a mudanças frequentes de contexto — alternar entre tarefas ou aplicativos — o que pode interromper o foco e reduzir a produtividade. Por exemplo, um usuário que trabalha em um projeto pode precisar alternar de seu aplicativo atual para o Outlook para encontrar detalhes cruciais em um email ou alternar para o OneDrive for Business para localizar um arquivo relacionado. Essa ação de ida e volta interrompe o foco e desperdiça tempo que poderia ser melhor gasto na tarefa em questão.
Para melhorar a eficiência, você pode integrar dados organizacionais diretamente nos aplicativos que os usuários usam todos os dias. Ao trazer dados organizacionais para seus aplicativos, os usuários podem acessar e gerenciar informações de forma mais perfeita, minimizando as mudanças de contexto e melhorando a produtividade. Além disso, essa integração fornece informações e contexto valiosos, permitindo que os usuários tomem decisões informadas e trabalhem de forma mais eficaz.
Neste exercício, irá:
- Saiba como o componente Web mgt-search-results no Microsoft Graph Toolkit pode ser usado para pesquisar arquivos.
- Saiba como chamar o Microsoft Graph diretamente para recuperar arquivos do OneDrive for Business e mensagens de bate-papo do Microsoft Teams.
- Entenda como enviar mensagens de bate-papo para canais do Microsoft Teams usando o Microsoft Graph.
Usando o recurso de dados organizacionais
Em um exercício anterior, você criou um registro de aplicativo 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>
Certifique-se de ter concluído o exercício anterior antes de continuar.
Volte ao navegador (http://localhost:4200). Se ainda não tiver iniciado sessão, selecione Iniciar sessão no cabeçalho e inicie sessão com um utilizador do seu inquilino do Microsoft 365 Developer.
Nota
Além de autenticar o usuário, o componente da Web mgt-login também recupera um token de acesso que pode ser usado pelo Microsoft Graph para acessar arquivos, chats, e-mails, eventos de calendário e outros dados organizacionais. O token de acesso contém os escopos (permissões), como
Chat.ReadWrite
,Files.Read.All
e outros que você viu anteriormente:Providers.globalProvider = new Msal2Provider({ clientId: ENTRAID_CLIENT_ID, // retrieved from .env file scopes: ['User.Read', 'Presence.Read', 'Chat.ReadWrite', 'Calendars.Read', 'ChannelMessage.Read.All', 'ChannelMessage.Send', 'Files.Read.All', 'Mail.Read'] });
Selecione Exibir Conteúdo Relacionado para a linha Adatum Corporation na grade de dados. Isso fará com que dados organizacionais, como arquivos, chats, e-mails e eventos de calendário, sejam recuperados usando o Microsoft Graph. Assim que os dados forem carregados, eles serão exibidos abaixo da grade de dados em uma interface com guias. É importante mencionar que você pode não ver nenhum dado neste momento, pois ainda não adicionou arquivos, bate-papos, e-mails ou eventos de calendário para o usuário em seu locatário de desenvolvedor do Microsoft 365. Vamos corrigir isso na próxima etapa.
Seu locatário do Microsoft 365 pode não ter nenhum dado organizacional relacionado para a Adatum Corporation neste estágio. Para adicionar alguns dados de exemplo, execute pelo menos uma das seguintes ações:
Adicione arquivos visitando https://onedrive.com e entrando usando suas credenciais de locatário do Microsoft 365 Developer.
- Selecione Meus arquivos na navegação à esquerda.
- Selecione + Adicionar novo e, em seguida, Carregar pasta no menu.
- Selecione a pasta openai-acs-msgraph/customer documents do 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 Microsoft 365 Developer.
Selecione Equipas no painel de navegação esquerdo.
Selecione uma equipa e um canal.
Selecione Iniciar uma publicação.
Insira Novo pedido feito para a Adatum Corporation para o assunto e qualquer texto adicional que você gostaria de adicionar no corpo da mensagem. Selecione o botão Postar .
Sinta-se à vontade para adicionar mensagens de bate-papo adicionais que mencionem outras empresas usadas no aplicativo, como Adventure Works Cycles, Contoso Pharmaceuticals e Tailwind Traders.
Selecione Calendário na navegação à esquerda.
Selecione Nova reunião.
Digite "Reunir-se com a Adatum Corporation sobre o cronograma do projeto" para o título e o corpo.
Selecione Guardar.
Adicione emails visitando https://outlook.com e entrando usando suas credenciais de locatário do Microsoft 365 Developer.
Selecione Novo e-mail.
Introduza o seu endereço de e-mail pessoal no campo Para .
Digite Novo pedido feito para a Adatum Corporation para o assunto e qualquer coisa que você gostaria para o corpo.
Selecione Enviar.
Volte para o aplicativo no navegador e atualize a página. Selecione Exibir Conteúdo Relacionado novamente para a linha Adatum Corporation . Agora você deve ver os dados exibidos nas guias, dependendo de quais tarefas você executou na etapa anterior.
Vamos explorar o código que habilita o recurso de dados organizacionais no aplicativo. Para recuperar os dados, a parte do lado do cliente do aplicativo usa o token de acesso recuperado pelo componente mgt-login que você examinou anteriormente para fazer chamadas para APIs do Microsoft Graph.
Explorando o código de pesquisa de arquivos
Gorjeta
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Vamos começar examinando como os dados de arquivo são recuperados do OneDrive for Business. Abra files.component.html e reserve um momento para examinar o código. O caminho completo para o arquivo é client/src/app/files/files.component.html.
Localize o componente mgt-search-results e observe os seguintes atributos:
<mgt-search-results class="search-results" entity-types="driveItem" [queryString]="searchText" (dataChange)="dataChange($any($event))" />
O componente mgt-search-results faz parte do Microsoft Graph Toolkit e, como o nome indica, é usado para exibir resultados de pesquisa do Microsoft Graph. O componente usa os seguintes recursos neste exemplo:
O
class
atributo é usado para especificar que asearch-results
classe CSS deve ser aplicada ao componente.O
entity-types
atributo é usado para especificar o tipo de dados a serem pesquisados. Nesse caso, o valor édriveItem
usado para pesquisar arquivos no OneDrive for Business.O
queryString
atributo é usado para especificar o termo de pesquisa. Nesse caso, o valor é vinculado àsearchText
propriedade que é passada para o componente files quando o usuário seleciona Exibir Conteúdo Relacionado para uma linha na grade de dados. Os colchetes ao redorqueryString
indicam que a propriedade está vinculada 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á ligado àdataChange()
função.Como nenhum modelo personalizado é fornecido, o modelo padrão incorporado
mgt-search-results
é usado para exibir os resultados da pesquisa.
Uma alternativa ao uso de componentes como mgt-search-results é chamar APIs do Microsoft Graph diretamente usando código. Para ver como isso funciona, abra o arquivo graph.service.ts e localize a
searchFiles()
função. O caminho completo para o arquivo é client/src/app/core/graph.service.ts.Você notará que um
query
parâmetro é passado para a função. Este é o termo de pesquisa que é passado quando o usuário seleciona Exibir Conteúdo Relacionado para uma linha na grade de dados. Se nenhum termo de pesquisa for passado, uma matriz vazia será retornada.async searchFiles(query: string) { const files: DriveItem[] = []; if (!query) return files; ... }
Em seguida, é criado um filtro que define o tipo de pesquisa a ser realizada. Nesse caso, o código está procurando por arquivos no OneDrive for Business, portanto,
driveItem
é usado exatamente como você viu anteriormente com omgt-search-results
componente. Isso é o mesmo que passardriveItem
paraentity-types
o componente mgt-search-results que você viu anteriormente. Oquery
parâmetro é então adicionado aoqueryString
filtro junto comContentType:Document
.const filter = { "requests": [ { "entityTypes": [ "driveItem" ], "query": { "queryString": `${query} AND ContentType:Document` } } ] };
Em seguida, é feita uma chamada para a API do
/search/query
Microsoft Graph usando aProviders.globalProvider.graph.client.api()
função. Ofilter
objeto é passado para apost()
função que envia os dados para a API.const searchResults = await Providers.globalProvider.graph.client.api('/search/query').post(filter);
Os resultados da pesquisa são então iterados para localizar
hits
. Cadahit
um contém informações sobre um documento que foi encontrado. Uma propriedade chamadaresource
contém os metadados do documento e é adicionadafiles
à matriz.if (searchResults.value.length !== 0) { for (const hitContainer of searchResults.value[0].hitsContainers) { if (hitContainer.hits) { for (const hit of hitContainer.hits) { files.push(hit.resource); } } } }
A
files
matriz é então devolvida ao chamador.return files;
Olhando através deste código, você pode ver que o componente web mgt-search-results que você explorou anteriormente faz muito trabalho para você e reduz significativamente a quantidade de código que você tem que escrever! No entanto, pode haver cenários em que você queira chamar o Microsoft Graph diretamente para ter mais controle sobre os dados enviados para a API ou como os resultados são processados.
Abra o arquivo files.component.ts e localize a
search()
função. O caminho completo para o arquivo é client/src/app/files/files.component.ts.Embora o corpo dessa função seja comentado devido ao componente mgt-search-results ser usado, a função pode ser usada para fazer a chamada para o Microsoft Graph quando o usuário seleciona Exibir Conteúdo Relacionado para uma linha na grade de dados. A
search()
função chamasearchFiles()
graph.service.ts e passa oquery
parâmetro para ela (o nome da empresa neste exemplo). Os resultados da pesquisa são então atribuídos àdata
propriedade do componente.override async search(query: string) { this.data = await this.graphService.searchFiles(query); }
O componente arquivos pode usar a
data
propriedade para exibir os resultados da pesquisa. Você pode lidar com isso usando associações HTML personalizadas ou usando outro controle do Microsoft Graph Toolkit chamadomgt-file-list
. Aqui está um exemplo de vinculação dadata
propriedade a uma das propriedades do componente nomeadasfiles
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 bate-papo do Teams
Volte para graph.service.ts e localize a
searchChatMessages()
função. Você verá que é semelhante àsearchFiles()
função que você olhou 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 para oteamId
,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 para
searchChatMessages()
o chamador.
- Ele posta dados de filtro na API do
Abra o arquivo chats.component.ts e localize a
search()
função. O caminho completo para o arquivo é client/src/app/chats/chats.component.ts. Asearch()
função chamasearchChatMessages()
graph.service.ts e passa oquery
parâmetro para ela.override async search(query: string) { this.data = await this.graphService.searchChatMessages(query); }
Os resultados da pesquisa são atribuídos à
data
propriedade do componente e a vinculação de dados é usada para iterar através da matriz de resultados e renderizar os dados. Este exemplo usa um componente de cartão Material Angular para exibir os resultados da pesquisa.@if (this.data.length) { <div> @for (chatMessage of this.data;track chatMessage.id) { <mat-card> <mat-card-header> <mat-card-title [innerHTML]="chatMessage.summary"></mat-card-title> <!-- <mat-card-subtitle [innerHTML]="chatMessage.body"></mat-card-subtitle> --> </mat-card-header> <mat-card-actions> <a mat-stroked-button color="basic" [href]="chatMessage.webUrl" target="_blank">View Message</a> </mat-card-actions> </mat-card> } </div> }
Enviar uma mensagem para um canal do Microsoft Teams
Além de procurar mensagens de bate-papo do Microsoft Teams, o aplicativo também permite que um usuário envie mensagens para um canal do Microsoft Teams. Isso pode ser feito chamando o
/teams/${teamId}/channels/${channelId}/messages
ponto de extremidade do Microsoft Graph.No código a seguir, você verá que uma URL é criada que inclui os
teamId
valores echannelId
. Os valores das variáveis de ambiente são usados para o ID da equipe e o ID do canal neste exemplo, mas esses valores também podem ser recuperados dinamicamente usando o Microsoft Graph. Abody
constante contém a mensagem a ser enviada. Uma solicitação POST é então feita e os resultados são retornados ao chamador.async sendTeamsChat(message: string): Promise<TeamsDialogData> { if (!message) new Error('No message to send.'); if (!TEAM_ID || !CHANNEL_ID) new Error('Team ID or Channel ID not set in environment variables. Please set TEAM_ID and CHANNEL_ID in the .env file.'); const url = `https://graph.microsoft.com/v1.0/teams/${TEAM_ID}/channels/${CHANNEL_ID}/messages`; const body = { "body": { "contentType": "html", "content": message } }; const response = await Providers.globalProvider.graph.client.api(url).post(body); return { id: response.id, teamId: response.channelIdentity.teamId, channelId: response.channelIdentity.channelId, message: response.body.content, webUrl: response.webUrl, title: 'Send Teams Chat' }; }
Aproveitar esse tipo de funcionalidade no Microsoft Graph fornece uma ótima maneira de aprimorar a produtividade do usuário, permitindo que os usuários interajam com o Microsoft Teams diretamente do aplicativo que já estão usando.
Dados organizacionais: Recuperando e-mails e eventos do calendário
No exercício anterior, você aprendeu como recuperar arquivos do OneDrive for Business e bate-papos do Microsoft Teams usando o Microsoft Graph e o componente mgt-search-results do Microsoft Graph Toolkit. Você também aprendeu como enviar mensagens para os canais do Microsoft Teams. Neste exercício, você aprenderá como recuperar mensagens de email e eventos de calendário do Microsoft Graph e integrá-los ao aplicativo.
Neste exercício, irá:
- Saiba como o componente Web mgt-search-results no Microsoft Graph Toolkit pode ser usado para pesquisar e-mails e eventos de calendário.
- Saiba como personalizar o componente mgt-search-results para renderizar os resultados da pesquisa de forma personalizada.
- Saiba como ligar diretamente para o Microsoft Graph para recuperar e-mails e eventos do calendário.
Explorando o código de pesquisa de mensagens de e-mail
Gorjeta
Se você estiver usando o Visual Studio Code, poderá abrir arquivos diretamente selecionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
Em seguida, digite o nome do arquivo que deseja abrir.
Em um exercício anterior, você criou um registro de aplicativo 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>
Certifique-se de ter concluído o exercício anterior antes de continuar.
Abra emails.component.html e reserve um momento para examinar o código. O caminho completo para o arquivo é client/src/app/emails/emails.component.html.
Localize o componente mgt-search-results :
<mgt-search-results class="search-results" entity-types="message" [queryString]="searchText" (dataChange)="dataChange($any($event))"> <template data-type="result-message"></template> </mgt-search-results>
Este exemplo do componente mgt-search-results é configurado da mesma maneira que o que você visualizou anteriormente. A única diferença é que o
entity-types
atributo é definido paramessage
o qual é usado para procurar mensagens de e-mail e um modelo vazio é fornecido.- O
class
atributo é usado para especificar que asearch-results
classe CSS deve ser aplicada ao componente. - O
entity-types
atributo é usado para especificar o tipo de dados a serem pesquisados. Neste caso, o valor émessage
. - O
queryString
atributo é usado para especificar o termo de pesquisa. - O
dataChange
evento é acionado quando os resultados da pesquisa são alterados. A função do componente e-mails é chamada, os resultados são passadosdataChange()
para ele e uma propriedade nomeadadata
é 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, nós mesmos renderizaremos os dados usando a vinculação de dados padrão (o Angular é usado neste caso, mas você pode usar qualquer biblioteca/estrutura que desejar).
- O
Procure abaixo o componente mgt-search-results no emails.component.html para encontrar as associações de dados usadas para renderizar as mensagens de e-mail. Este exemplo itera
data
pela propriedade e grava o assunto do e-mail, a visualização do corpo e um link para exibir a mensagem de email completa.@if (this.data.length) { <div> @for (email of this.data;track $index) { <mat-card> <mat-card-header> <mat-card-title>{{email.resource.subject}}</mat-card-title> <mat-card-subtitle [innerHTML]="email.resource.bodyPreview"></mat-card-subtitle> </mat-card-header> <mat-card-actions> <a mat-stroked-button color="basic" [href]="email.resource.webLink" target="_blank">View Email Message</a> </mat-card-actions> </mat-card> } </div> }
Além de usar o componente mgt-search-results para recuperar mensagens, o Microsoft Graph fornece várias APIs que também podem ser usadas para pesquisar e-mails. 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 procura oquery
valor nos campos assunto, corpo e remetente automaticamente.async searchEmailMessages(query:string) { if (!query) return []; // The $search operator will search the subject, body, and sender fields automatically const url = `https://graph.microsoft.com/v1.0/me/messages?$search="${query}"&$select=subject,bodyPreview,from,toRecipients,receivedDateTime,webLink`; const response = await Providers.globalProvider.graph.client.api(url).get(); return response.value; }
O componente de e-mails localizado em emails.component.ts chamadas
searchEmailMessages()
e exibe os resultados na interface do usuário.override async search(query: string) { this.data = await this.graphService.searchEmailMessages(query); }
Explorando o código de pesquisa de eventos do calendário
A pesquisa de eventos do 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á mais adiante neste exercício.
Abra calendar-events.component.html e reserve um momento para examinar o código. O caminho completo para o arquivo é client/src/app/calendar-events/calendar-events.component.html. Você verá que é muito semelhante aos componentes de arquivos e e-mails que você olhou anteriormente.
<mgt-search-results class="search-results" entity-types="event" [queryString]="searchText" (dataChange)="dataChange($any($event))"> <template data-type="result-event"></template> </mgt-search-results>
Este exemplo do componente mgt-search-results é configurado da mesma forma que os que você visualizou anteriormente. A única diferença é que o
entity-types
atributo é definido paraevent
o qual é usado para procurar eventos de calendário e um modelo vazio é fornecido.- O
class
atributo é usado para especificar que asearch-results
classe CSS deve ser aplicada ao componente. - O
entity-types
atributo é usado para especificar o tipo de dados a serem pesquisados. Neste caso, o valor éevent
. - O
queryString
atributo é usado para especificar o termo de pesquisa. - O
dataChange
evento é acionado quando os resultados da pesquisa são alterados. A função do componente de evento de calendário é chamada, os resultados são passadosdataChange()
para ele e uma propriedade nomeadadata
é atualizada no componente. - Um modelo vazio é definido para o componente. Neste cenário, estamos dizendo ao componente para não renderizar nenhum dado. Em vez disso, nós mesmos renderizaremos os dados usando a vinculação de dados padrão.
- O
Imediatamente abaixo do
mgt-search-results
componente em calendar-events.component.html você encontrará as associações de dados usadas para renderizar os eventos do calendário. Este exemplo iteradata
pela 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 especificado.@if (this.data.length) { <div> @for (event of this.data;track $index) { <div class="root"> <div class="time-container"> <div class="date">{{ dayFromDateTime(event.resource.start.dateTime)}}</div> <div class="time">{{ timeRangeFromEvent(event.resource) }}</div> </div> <div class="separator"> <div class="vertical-line top"></div> <div class="circle"> @if (!this.event.resource.bodyPreview?.includes('Join Microsoft Teams Meeting')) { <div class="inner-circle"></div> } </div> <div class="vertical-line bottom"></div> </div> <div class="details"> <div class="subject">{{ event.resource.subject }}</div> @if (this.event.resource.location?.displayName) { <div class="location"> at <a href="https://bing.com/maps/default.aspx?where1={{event.resource.location.displayName}}" target="_blank" rel="noopener"><b>{{ event.resource.location.displayName }}</b></a> </div> } @if (this.event.resource.attendees?.length) { <div class="attendees"> @for (attendee of this.event.resource.attendees;track attendee.emailAddress.name) { <span class="attendee"> <mgt-person person-query="{{attendee.emailAddress.name}}"></mgt-person> </span> } </div> } @if (this.event.resource.bodyPreview?.includes('Join Microsoft Teams Meeting')) { <div class="online-meeting"> <img class="online-meeting-icon" src="https://img.icons8.com/color/48/000000/microsoft-teams.png" title="Online Meeting" /> <a class="online-meeting-link" href="{{ event.resource.onlineMeetingUrl }}"> Join Teams Meeting </a> </div> } </div> </div> } </div> }
Além de pesquisar eventos de calendário usando a API, o
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 no 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 fim. Uma solicitação GET é então 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 do URL criado:
- A
/me/events
parte da URL é usada para especificar que os eventos do usuário conectado devem ser recuperados. - Os
startdatetime
parâmetros eenddatetime
são usados para definir o período de tempo para pesquisar. Neste caso, a pesquisa retornará eventos que começam nos próximos 7 dias. - O
$filter
parâmetro query é usado para filtrar os resultados peloquery
valor (o nome da empresa selecionado na grade de dados neste caso). Acontains()
função é usada para procurar oquery
valor nasubject
propriedade do evento 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 para a API do Microsoft Graph usando o valor de e os resultados são retornadosurl
para o chamador.Como nos componentes anteriores, o componente de eventos de calendário (arquivo calendar-events.component.ts) chama
search()
e exibe os resultados.override async search(query: string) { this.data = await this.graphService.searchCalendarEvents(query); }
Nota
Você também pode fazer chamadas do Microsoft Graph a partir de uma API personalizada ou de um aplicativo do lado do servidor. Veja o tutorial a seguir para ver um exemplo de como chamar uma API do Microsoft Graph a partir de uma Função do Azure.
Agora você viu exemplos de como usar o Microsoft Graph para recuperar arquivos, bate-papos, mensagens de email e eventos de calendário. Os mesmos conceitos também podem ser aplicados a outras APIs do Microsoft Graph. Por exemplo, você pode usar a API de usuários do Microsoft Graph para pesquisar usuários em sua organização. Você também pode usar a API de grupos do Microsoft Graph para pesquisar grupos em sua organização. Você pode exibir a lista completa de APIs do Microsoft Graph na documentação.
Parabéns!
Você concluiu este tutorial
Parabéns! Neste tutorial você aprendeu como:
- O Azure OpenAI pode ser usado para melhorar a produtividade do usuário.
- Os Serviços de Comunicação do Azure podem ser usados para integrar recursos de comunicação.
- As APIs e os componentes do Microsoft Graph podem ser usados para recuperar e exibir dados organizacionais.
Usando essas tecnologias, você pode criar soluções eficazes que aumentam a produtividade do usuário, minimizando as mudanças de contexto e fornecendo as informações necessárias para a tomada de decisões.
Limpar recursos do Azure
Limpe seus recursos do Azure para evitar mais cobranças em sua conta. Vá para o portal do Azure e exclua os seguintes recursos:
- Recurso Azure AI Search
- Recurso de Armazenamento do Azure
- Recurso OpenAI do Azure (certifique-se de excluir seus modelos primeiro e, em seguida, o recurso do Azure OpenAI)
- Recurso dos Serviços de Comunicação do Azure
Passos Seguintes
Documentação
- Documentação do Azure OpenAI
- Azure OpenAI em seus dados
- Documentação dos Serviços de Comunicação do Azure
- Documentação do Microsoft Graph
- Documentação do Microsoft Graph Toolkit
- Documentação do Microsoft Teams Developer
Conteúdo de Formação
- Aplicar engenharia de prompt com o Serviço OpenAI do Azure
- Introdução ao Serviço OpenAI do Azure
- Introdução aos Serviços de Comunicação do Azure
- Fundamentos do Microsoft Graph
- Curso em vídeo: Fundamentos do Microsoft Graph para iniciantes
- Explore os cenários do Microsoft Graph para desenvolvimento JavaScript
- Explore os cenários do Microsoft Graph para o desenvolvimento do ASP.NET Core
- Introdução ao Microsoft Graph Toolkit
- Criar e implantar aplicativos para o Microsoft Teams usando o Teams Toolkit for Visual Studio Code
Está com problemas nesta secção? Se sim, envie-nos o seu feedback para que possamos melhorar esta secção.