LoB(기간 업무) 앱에 OpenAI, Communication 및 조직 데이터 기능 통합
수준: 중간
이 자습서에서는 Azure OpenAI, Azure Communication Services 및 Microsoft Graph/Microsoft Graph 도구 키트를 LOB(기간 업무) 애플리케이션에 통합하여 사용자 생산성을 향상시키고, 사용자 환경을 높이고, LOB 앱을 다음 단계로 끌어올리는 방법을 보여 줍니다. 애플리케이션의 주요 기능은 다음과 같습니다.
- AI: 사용자가 자연어로 질문을 하고 대답을 데이터베이스를 쿼리하는 데 사용할 수 있는 SQL로 변환하고, 사용자가 전자 메일 및 SMS 메시지를 자동으로 생성하는 데 사용할 수 있는 규칙을 정의하고, 자연어를 사용하여 사용자 지정 데이터 원본에서 데이터를 검색하는 방법을 알아볼 수 있습니다. Azure OpenAI는 이러한 기능에 사용됩니다.
- 통신: Azure Communication Services를 사용하여 고객에게 앱 내 전화 통화 및 이메일/SMS 기능을 사용하도록 설정합니다.
- 조직 데이터: 컨텍스트 전환을 방지하기 위해 고객과 함께 작업할 때 사용자에게 필요할 수 있는 관련 조직 데이터(문서, 채팅, 전자 메일, 일정 이벤트)를 가져옵니다. 이러한 유형의 조직 데이터에 대한 액세스를 제공하면 필요한 특정 데이터와 기능이 앱에서 직접 제공되므로 사용자가 Outlook, Teams, OneDrive, 기타 사용자 지정 앱, 휴대폰 등으로 전환할 필요가 줄어듭니다. 이 기능에는 Microsoft Graph 및 Microsoft Graph 도구 키트가 사용됩니다.
애플리케이션은 사용자가 고객 및 관련 데이터를 관리할 수 있는 간단한 고객 관리 앱입니다. 백 엔드 API를 호출하여 데이터를 검색하고, AI 기능과 상호 작용하고, 전자 메일/SMS 메시지를 보내고, 조직 데이터를 끌어오는 TypeScript를 사용하여 빌드된 프런트 엔드로 구성됩니다. 다음은 이 자습서에서 살펴볼 애플리케이션 솔루션의 개요입니다.
이 자습서에서는 필요한 Azure 및 Microsoft 365 리소스를 설정하는 과정을 안내합니다. 또한 AI, 통신 및 조직 데이터 기능을 구현하는 데 사용되는 코드를 안내합니다. 코드를 복사하여 붙여넣을 필요는 없지만, 일부 연습에서는 코드를 수정하여 다양한 시나리오를 시도해 볼 수 있습니다.
이 자습서에서 빌드할 내용
나만의 모험 선택
전체 자습서를 처음부터 완료하거나 관심 있는 특정 항목을 완료할 수 있습니다. 이 자습서는 다음 항목으로 세분화되어 있습니다.
- 프로젝트 연습(필수 연습 )을 복제합니다.
- AI 연습: Azure OpenAI 리소스를 만들고 이를 사용하여 자연어를 SQL로 변환하고, 이메일/SMS 메시지를 생성하고, 사용자 고유의 데이터 및 문서를 사용합니다.
- 통신 연습: Azure Communication Services 리소스를 만들고 이를 사용하여 앱에서 전화를 걸고 이메일/SMS 메시지를 보냅니다.
- 조직 데이터 연습: Microsoft Graph 및 Microsoft Graph 도구 키트를 사용하여 조직 데이터를 인증하고 애플리케이션으로 끌어올 수 있도록 Microsoft Entra ID 앱 등록 을 만듭니다.
필수 조건
- 노드 - 이 프로젝트에 노드 20 이상 및 npm 10 이상이 사용됩니다.
- git
- Visual Studio Code (Visual Studio Code를 권장하지만 모든 편집기를 사용할 수 있습니다).
- Azure 구독
- Microsoft 365 개발자 테넌트
- Docker Desktop 또는 다른 OCI(Open Container Initiative) Podman과 같은 규격 컨테이너 런타임 또는 컨테이너를 실행할 수 있는 nerdctl입니다.
이 자습서에서 사용되는 Microsoft Cloud Technologies
- Azure Communication Services
- Azure OpenAI Service
- Microsoft Entra ID
- Microsoft Graph
- Microsoft Graph Toolkit
프로젝트 복제
이 자습서에서 사용되는 코드 프로젝트는 .에서 https://github.com/microsoft/MicrosoftCloud사용할 수 있습니다. 프로젝트의 리포지토리에는 프로젝트를 실행하는 데 필요한 클라이언트 쪽 코드와 서버 쪽 코드가 모두 포함되어 있으므로 AI(인공 지능), 통신 및 조직 데이터와 관련된 통합된 기능을 탐색할 수 있습니다. 또한 이 프로젝트는 유사한 기능을 사용자 고유의 애플리케이션에 통합하는 데 도움이 되는 리소스 역할을 합니다.
이 연습에서 다음을 수행합니다.
- GitHub 리포지토리를 복제합니다.
- 프로젝트에 .env 파일을 추가하고 업데이트합니다.
계속하기 전에 이 자습서의 필수 구성 요소 섹션에 설명된 대로 모든 필수 구성 요소를 설치하고 구성했는지 확인합니다 .
GitHub 리포지토리 복제 및 파일 만들기 .env
다음 명령을 실행하여 Microsoft Cloud GitHub 리포지토리를 컴퓨터에 복제합니다.
git clone https://github.com/microsoft/MicrosoftCloud
Visual Studio Code에서 MicrosoftCloud/samples/openai-acs-msgraph 폴더를 엽니다.
참고 항목
이 자습서 전체에서 Visual Studio Code를 사용하지만 모든 코드 편집기를 사용하여 샘플 프로젝트를 사용할 수 있습니다.
다음 폴더 및 파일을 확인합니다.
- client: 클라이언트 쪽 애플리케이션 코드입니다.
- 서버: 서버 쪽 API 코드입니다.
- docker-compose.yml: 로컬 PostgreSQL 데이터베이스를 실행하는 데 사용됩니다.
프로젝트의 루트에 있는 .env.example의 이름을 .env로 바꿉니다.
.env 파일을 열고 포함된 키를 살펴보세요.
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=
.env에서 다음 값을 업데이트합니다. 이러한 값은 API 서버에서 로컬 PostgreSQL 데이터베이스에 연결하는 데 사용됩니다.
POSTGRES_USER=web POSTGRES_PASSWORD=web-password
이제 프로젝트가 시작되었으므로 애플리케이션 기능 중 일부를 사용해보고 빌드 방법을 알아보겠습니다. 목차를 사용하여 특정 연습을 계속하거나 이동하려면 아래의 다음 단추를 선택합니다.
AI: Azure OpenAI 리소스 만들기 및 모델 배포
애플리케이션에서 Azure OpenAI 사용을 시작하려면 Azure OpenAI 서비스를 만들고 자연어를 SQL로 변환, 이메일/SMS 메시지 콘텐츠 생성 등의 작업을 수행하는 데 사용할 수 있는 모델을 배포해야 합니다.
이 연습에서 다음을 수행합니다.
- Azure OpenAI 서비스 리소스를 만듭니다.
- 모델 배포
- .env 파일을 Azure OpenAI 서비스 리소스의 값으로 업데이트합니다.
Azure OpenAI 서비스 리소스 만들기
브라우저에서 Azure Portal 을 방문하여 로그인합니다.
포털 페이지의 맨 위에 있는 검색 창에 openai를 입력하고 표시되는 옵션에서 Azure OpenAI를 선택합니다.
도구 모음에서 만들기를 선택합니다.
참고 항목
이 자습서에서는 Azure OpenAI에 중점을 두고 있지만 OpenAI API 키가 있고 사용하려는 경우 이 섹션을 건너뛰고 아래 프로젝트의 .env 파일 업데이트 섹션으로 직접 이동하면 됩니다. .env 파일에 OpenAI API 키를
OPENAI_API_KEY
할당합니다(OpenAI와 관련된 다른.env
지침은 무시할 수 있습니다).Azure OpenAI 모델은 특정 지역에서 사용할 수 있습니다. Azure OpenAI 모델 가용성 문서를 방문하여 이 자습서에서 사용되는 gpt-4o 모델을 지원하는 지역을 알아봅니다.
다음 작업을 수행합니다.
- Azure 구독을 선택합니다.
- 사용할 리소스 그룹을 선택합니다(필요한 경우 새 리소스 그룹 만들기).
- 앞에서 살펴본 문서를 기반으로 gpt-4o 모델이 지원되는 지역을 선택합니다.
- 리소스 이름을 입력합니다. 고유한 값이어야 합니다.
- 표준 S0 가격 책정 계층을 선택합니다.
검토 + 제출 화면이 표시될 때까지 다음을 선택합니다. 만들기를 실행합니다.
Azure OpenAI 리소스가 만들어지면 해당 리소스로 이동하여 리소스 관리 --키 및 엔드포인트를 선택합니다>
KEY 1 및 엔드포인트 값을 찾습니다. 다음 섹션에서 두 값을 모두 사용하므로 로컬 파일에 복사합니다.
리소스 관리 --> 선택합니다.
배포 관리 단추를 선택하여 Azure OpenAI Studio로 이동합니다.
도구 모음에서 모델 배포 --> 배포를 선택합니다.
모델 목록에서 gpt-4o를 선택하고 확인을 선택합니다.
참고 항목
Azure OpenAI는 여러 가지 유형의 모델을 지원합니다. 각 모델을 사용하여 다양한 시나리오를 처리할 수 있습니다.
다음 대화 상자가 표시됩니다. 잠시 시간을 내어 제공된 기본값을 검사합니다.
분당 토큰 속도 제한(천)을 100K로 변경합니다. 이렇게 하면 모델에 대한 더 많은 요청을 수행하고 다음 단계를 수행할 때 속도 제한에 도달하는 것을 방지할 수 있습니다.
배포를 선택합니다.
모델이 배포되면 플레이그라운드 -->을 선택합니다.
배포 드롭다운에는 gpt-4o 모델이 표시됩니다.
잠시 시간을 내어 제공된 시스템 메시지 텍스트를 읽어 보십시오. 이렇게 하면 사용자가 상호 작용하는 역할을 하는 방법을 모델에 알릴 수 있습니다.
채팅 영역에서 텍스트 상자를 찾아 생성 AI의 내용과 사용 방법을 요약으로 입력합니다. Enter 키를 선택하여 모델에 메시지를 보내고 응답을 생성하도록 합니다.
다른 프롬프트 및 응답을 실험합니다. 예를 들어 프랑스의 수도에 대한 짧은 기록을 입력하고 생성된 응답을 확인합니다.
프로젝트의 .env
파일 업데이트
Visual Studio Code로 돌아가서 프로젝트의 루트에서 파일을 엽니다
.env
.Azure OpenAI 리소스에서 KEY 1 값을 복사하고 openai-acs-msgraph
OPENAI_API_KEY
루트에 있는 .env 파일에 할당 합니다.OPENAI_API_KEY=<KEY_1_VALUE>
*엔드포인트 값을 복사하여 .env 파일에 할당
OPENAI_ENDPOINT
합니다. 값이/
있는 경우 값의 끝에서 문자를 제거합니다.OPENAI_ENDPOINT=<ENDPOINT_VALUE>
참고 항목
해당 값
OPENAI_MODEL
OPENAI_API_VERSION
이 .env 파일에 이미 설정되어 있는 것을 볼 수 있습니다. 모델 값은 이 연습의 앞부분에서 만든 모델 배포 이름과 일치하는 gpt-4o로 설정됩니다. API 버전은 Azure OpenAI 참조 설명서에 정의된 지원되는 값으로 설정됩니다..env 파일을 저장합니다.
Application Services 시작
이제 데이터베이스, API 서버 및 웹 서버를 비롯한 애플리케이션 서비스를 시작할 차례입니다.
다음 단계에서는 Visual Studio Code에서 세 개의 터미널 창을 만듭니다.
Visual Studio Code 파일 목록에서 .env 파일을 마우스 오른쪽 단추로 클릭하고 통합 터미널에서 열기를 선택합니다. 계속하기 전에 터미널이 프로젝트의 루트인 openai-acs-msgraph 에 있는지 확인합니다.
다음 옵션 중 하나를 선택하여 PostgreSQL 데이터베이스를 시작합니다.
Docker Desktop을 설치하고 실행 중인 경우 터미널 창에서 실행하고
docker-compose up
Enter 키를 누릅니다.Podman-compose가 설치되고 실행 중인 Podman이 있는 경우 터미널 창에서 실행하고
podman-compose up
Enter 키를 누릅니다.Docker Desktop, Podman, nerdctl 또는 설치한 다른 컨테이너 런타임을 사용하여 PostgreSQL 컨테이너를 직접 실행하려면 터미널 창에서 다음 명령을 실행합니다.
Mac, Linux 또는 Linux용 Windows 하위 시스템(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
PowerShell이 있는 Windows:
[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
데이터베이스 컨테이너가 시작되면 Visual Studio Code +의 아이콘을 눌러 두 번째 터미널 창을 만듭니다.
cd
서버/typescript 폴더로 이동하고 다음 명령을 실행하여 종속성을 설치하고 API 서버를 시작합니다.npm install
npm start
+ Visual Studio Code 터미널 도구 모음에서 아이콘을 다시 눌러 세 번째 터미널 창을 만듭니다.
cd
클라이언트 폴더에 다음 명령을 실행하여 종속성을 설치하고 웹 서버를 시작합니다.npm install
npm start
브라우저가 시작되고 이 브라우저로 이동 http://localhost:4200됩니다.
AI: 자연어에서 SQL로
"반드시 해야 한다는 뜻은 아닙니다"라는 인용문은 AI 기능을 고려할 때 유용한 가이드입니다. 예를 들어 Azure OpenAI의 자연어-SQL 기능을 사용하면 사용자가 일반 영어로 데이터베이스 쿼리를 만들 수 있으므로 생산성을 향상시키는 강력한 도구가 될 수 있습니다. 그러나 강력한 것이 항상 적절하거나 안전하다는 의미는 아닙니다. 이 연습에서는 구현을 결정하기 전에 유의해야 할 중요한 고려 사항에 대해서도 논의하면서 이 AI 기능을 사용하는 방법을 보여 줍니다.
다음은 데이터베이스에서 데이터를 검색하는 데 사용할 수 있는 자연어 쿼리의 예입니다.
Get the the total revenue for all companies in London.
적절한 프롬프트를 사용하면 Azure OpenAI는 이 쿼리를 데이터베이스에서 결과를 반환하는 데 사용할 수 있는 SQL로 변환합니다. 따라서 비즈니스 분석가, 마케터 및 임원을 비롯한 비기술 사용자는 복잡한 SQL 구문을 사용하거나 제한된 데이터 그리드 및 필터를 사용하지 않고도 데이터베이스에서 중요한 정보를 보다 쉽게 검색할 수 있습니다. 이 간소화된 접근 방식은 사용자가 기술 전문가의 도움을 구할 필요가 없도록 하여 생산성을 높일 수 있습니다.
이 연습에서는 SQL에 대한 자연어 작동 방식을 이해하고, 몇 가지 중요한 고려 사항을 소개하고, 장단점에 대해 생각하고, 시작할 코드를 보여 주는 데 도움이 되는 시작 지점을 제공합니다.
이 연습에서 다음을 수행합니다.
- GPT 프롬프트를 사용하여 자연어를 SQL로 변환합니다.
- 다른 GPT 프롬프트를 사용하여 실험합니다.
- 생성된 SQL을 사용하여 이전에 시작된 PostgreSQL 데이터베이스를 쿼리합니다.
- PostgreSQL에서 쿼리 결과를 반환하고 브라우저에 표시합니다.
먼저 자연어를 SQL로 변환하는 데 사용할 수 있는 다양한 GPT 프롬프트를 실험해 보겠습니다.
자연어에서 SQL 기능 사용
이전 연습에서는 데이터베이스, API 및 애플리케이션을 시작했습니다. 또한 파일을 업데이트했습니다
.env
. 이러한 단계를 완료하지 않은 경우 계속하기 전에 연습의 끝에 있는 지침을 따릅니다.브라우저(http://localhost:4200)로 돌아가서 datagrid 아래 페이지의 사용자 지정 쿼리 섹션을 찾습니다. 샘플 쿼리 값이 이미 포함되어 있습니다. 모든 주문에 대한 총 수익을 가져옵니다. 회사별로 그룹화하고 도시를 포함합니다.
쿼리 실행 단추를 선택합니다. 그러면 사용자의 자연어 쿼리가 Azure OpenAI에 전달되어 SQL로 변환됩니다. 그런 다음 SQL 쿼리를 사용하여 데이터베이스를 쿼리하고 잠재적인 결과를 반환합니다.
다음 사용자 지정 쿼리를 실행합니다.
Get the total revenue for Adventure Works Cycles. Include the contact information as well.
Visual Studio Code에서 API 서버를 실행하는 터미널 창을 보고 Azure OpenAI에서 반환된 SQL 쿼리를 표시합니다. JSON 데이터는 서버 쪽 API에서 PostgreSQL 데이터베이스를 쿼리하는 데 사용됩니다. 쿼리에 포함된 모든 문자열 값은 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"] }
브라우저로 돌아가서 데이터 다시 설정을 선택하여 Datagrid 에서 모든 고객을 다시 봅니다.
자연어를 SQL 코드로 탐색
팁
Visual Studio Code를 사용하는 경우 다음을 선택하여 파일을 직접 열 수 있습니다.
- Windows/Linux: Ctrl+P
- Mac: Cmd + P
그런 다음 열려는 파일의 이름을 입력합니다.
참고 항목
이 연습의 목표는 자연어에서 SQL 기능으로 가능한 기능을 보여주고 사용을 시작하는 방법을 보여 주는 것입니다. 앞에서 설명한 것처럼 구현을 진행하기 전에 이러한 유형의 AI가 조직에 적합한지 논의하는 것이 중요합니다. 또한 무단 액세스를 방지하고 중요한 데이터를 보호하기 위해 적절한 프롬프트 규칙 및 데이터베이스 보안 조치를 계획해야 합니다.
이제 SQL에 대한 자연어 기능이 작동하는 것을 살펴보았으므로 구현 방법을 살펴보겠습니다.
서버/apiRoutes.ts 파일을 열고 경로를 찾습니다
generateSql
. 이 API 경로는 브라우저에서 실행되는 클라이언트 쪽 애플리케이션에서 호출되며 자연어 쿼리에서 SQL을 생성하는 데 사용됩니다. SQL 쿼리가 검색되면 데이터베이스를 쿼리하고 결과를 반환하는 데 사용됩니다.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.' }); } });
경로에서 다음 기능을 확인합니다
generateSql
.- 사용자 쿼리 값을
req.body.prompt
검색하여 명명userPrompt
된 변수에 할당합니다. 이 값은 GPT 프롬프트에서 사용됩니다. - 자연어를 SQL로
getSQLFromNLP()
변환하는 함수를 호출합니다. - 생성된 SQL을 SQL 쿼리를 실행하고 데이터베이스의 결과를 반환하는 함수
queryDb
에 전달합니다.
- 사용자 쿼리 값을
편집기에서 서버/openAI.ts 파일을 열고 함수를 찾습니다
getSQLFromNLP()
. 이 함수는 경로에서generatesql
호출되며 자연어를 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; }
-
userPrompt
매개 변수가 함수에 전달됩니다. 값은userPrompt
브라우저에서 사용자가 입력한 자연어 쿼리입니다. - A
systemPrompt
는 사용할 AI 도우미의 유형과 따라야 하는 규칙을 정의합니다. 이를 통해 Azure OpenAI는 데이터베이스 구조, 적용할 규칙 및 생성된 SQL 쿼리 및 매개 변수를 반환하는 방법을 이해할 수 있습니다. - 명명된
callOpenAI()
함수가 호출되고systemPrompt
값이userPrompt
전달됩니다. - 생성된 SQL 쿼리에 금지된 값이 포함되지 않도록 결과를 확인합니다. 금지된 값을 발견하면 SQL 쿼리가 빈 문자열로 설정됩니다.
-
시스템 프롬프트를 자세히 살펴보겠습니다.
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"] } `;
사용할 AI 도우미 유형이 정의됩니다. 이 경우 "SQL 봇에 대한 자연어"입니다.
데이터베이스의 테이블 이름 및 열이 정의됩니다. 프롬프트에 포함된 상위 수준 스키마는 server/db.schema 파일에서 찾을 수 있으며 다음과 같습니다.
- 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)
팁
SQL에 자연어를 사용하여 쿼리할 수 있는 데이터 사용자만 포함된 읽기 전용 보기를 만드는 것이 좋습니다.
SQL 삽입 공격을 방지하기 위해 문자열 값을 매개 변수가 있는 쿼리 값으로 변환하는 규칙이 정의됩니다.
규칙은 항상 SQL 쿼리 및 매개 변수 값을 사용하여 JSON 개체를 반환하도록 정의됩니다.
사용자 프롬프트 예제와 예상 SQL 쿼리 및 매개 변수 값이 제공됩니다. 이를 "몇 번의 학습"이라고 합니다. LLM은 많은 양의 데이터에 대해 학습되지만 몇 가지 예제만 사용하여 새 작업에 적응할 수 있습니다. 다른 방법은 예제가 제공되지 않고 모델이 올바른 SQL 쿼리 및 매개 변수 값을 생성해야 하는 "제로샷" 학습입니다.
이 함수는
getSQLFromNLP()
시스템 및 사용자 프롬프트를 서버/openAI.tscallOpenAI()
함수로 보냅니다. 이 함수는callOpenAI()
환경 변수를 확인하여 Azure OpenAI 서비스 또는 OpenAI 서비스를 호출해야 하는지 여부를 결정합니다. 환경 변수에서 키, 엔드포인트 및 모델을 사용할 수 있는 경우 Azure OpenAI가 호출되고, 그렇지 않으면 OpenAI가 호출됩니다.function callOpenAI(systemPrompt: string, userPrompt: string, temperature = 0, useBYOD = false) { const isAzureOpenAI = OPENAI_API_KEY && OPENAI_ENDPOINT && OPENAI_MODEL; if (isAzureOpenAI) { if (useBYOD) { return getAzureOpenAIBYODCompletion(systemPrompt, userPrompt, temperature); } return getAzureOpenAICompletion(systemPrompt, userPrompt, temperature); } return getOpenAICompletion(systemPrompt, userPrompt, temperature); }
참고 항목
이 자습서 전체에서 Azure OpenAI에 집중하지만 .env
OPENAI_API_KEY
제공하는 경우 애플리케이션은 OpenAI를 대신 사용합니다. Azure OpenAI 대신 OpenAI를 사용하도록 선택하는 경우 경우에 따라 다른 결과가 나타날 수 있습니다.함수를 찾습니다
getAzureOpenAICompletion()
.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; }
이 함수는 다음을 수행합니다.
매개 변수:
-
systemPrompt
,userPrompt
및temperature
기본 매개 변수입니다.-
systemPrompt
: Azure OpenAI 모델에 해당 역할 및 따라야 할 규칙을 알릴 수 있습니다. -
userPrompt
: 자연어 입력 또는 출력 생성 규칙과 같은 사용자가 제공한 정보를 포함합니다. -
temperature
: 모델 응답의 창의성 수준을 지정합니다. 값이 높을수록 더 창의적인 출력이 생성됩니다.
-
-
완료 생성:
- 함수는 ,
createAzureOpenAICompletion()
를systemPrompt
호출userPrompt
하고temperature
완료를 생성합니다. - 완료 시 첫 번째 선택 항목에서 콘텐츠를 추출하여 추가 공백을 트리밍합니다.
- 콘텐츠에 JSON과 유사한 구조체(있는 것으로 표시됨
{
}
)가 포함된 경우 JSON 콘텐츠를 추출합니다.
- 함수는 ,
로깅 및 반환 값:
- 이 함수는 Azure OpenAI 출력을 콘솔에 기록합니다.
- 처리된 콘텐츠를 문자열로 반환합니다.
함수를 찾습니다
createAzureOpenAICompletion()
.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.`); } } }
이 함수는 다음을 수행합니다.
매개 변수:
-
systemPrompt
,userPrompt
및temperature
앞에서 설명한 주요 매개 변수입니다. - 선택적
dataSources
매개 변수는 이 자습서의 뒷부분에서 다룰 "Azure Bring Your Own Data" 기능을 지원합니다.
-
환경 변수 확인:
- 이 함수는 필수 환경 변수가 있는지 확인하고 누락된 경우 오류를 throw합니다.
구성 개체:
-
config
개체는 파일(.env
, ,OPENAI_API_KEY
,OPENAI_ENDPOINT
OPENAI_API_VERSION
)의OPENAI_MODEL
값을 사용하여 만들어집니다. 이러한 값은 Azure OpenAI를 호출하기 위한 URL을 생성하는 데 사용됩니다.
-
AzureOpenAI 인스턴스:
-
AzureOpenAI
를 사용하여config
인스턴스가 생성됩니다. 기호는AzureOpenAI
파일의 맨 위에서 가져와야 하는 패키지의 일부입니다openai
.
-
완료 생성:
- 함수
chat.completions.create()
는 다음 속성을 사용하여 호출됩니다.-
model
: 파일에 정의된 GPT 모델(예: gpt-4o, gpt-3.5-turbo)을 지정합니다.env
. -
max_tokens
: 완료할 최대 토큰 수를 정의합니다. -
temperature
: 샘플링 온도를 설정합니다. 값(예: 0.9)이 높을수록 창의적인 응답이 늘어나고, 값이 낮을수록(예: 0) 더 결정적인 답변이 생성됩니다. -
response_format
: 응답 형식을 정의합니다. 여기서는 JSON 개체를 반환하도록 설정됩니다. JSON 모드에 대한 자세한 내용은 Azure OpenAI 참조 설명서에서 확인할 수 있습니다. -
messages
: 채팅 완료를 생성하기 위한 메시지를 포함합니다. 이 예제에는 시스템의 메시지(동작 및 규칙 정의)와 사용자의 메시지(프롬프트 텍스트 포함)의 두 메시지가 포함됩니다.
-
- 함수
Return Value(반환 값):
- 이 함수는 Azure OpenAI에서 생성된 완료 개체를 반환합니다.
함수에서 다음 줄을 주석 처리합니다
getSQLFromNLP()
.// if (isProhibitedQuery(queryData.sql)) { // queryData.sql = ''; // }
openAI.ts 저장합니다. API 서버는 TypeScript 코드를 자동으로 다시 빌드하고 서버를 다시 시작합니다.
브라우저로 돌아가서 데이터베이스의 모든 테이블 이름 선택을 사용자 지정 쿼리 입력에 입력합니다. 쿼리 실행을 선택합니다. 테이블 이름이 표시되어 있나요?
서버/openAI.ts
getSQLFromNLP()
로 돌아가 서 시스템 프롬프트의 섹션에Rules:
다음 규칙을 추가한 다음 파일을 저장합니다.- Do not allow the SELECT query to return table names, function names, or procedure names.
브라우저로 돌아가서 다음 작업을 수행합니다.
- 데이터베이스의 모든 테이블 이름을 사용자 지정 쿼리 입력에 입력합니다. 쿼리 실행을 선택합니다. 테이블 이름이 표시되어 있나요?
- 데이터베이스에서 모든 함수 이름을 선택합니다. 사용자 지정 쿼리 입력에 입력하고 쿼리 실행을 다시 선택합니다. 함수 이름이 표시되어 있나요?
질문: 모델은 항상 프롬프트에서 정의하는 규칙을 따르나요?
대답: 아니요! OpenAI 모델은 정의한 규칙과 일치하지 않을 수 있는 경우에 따라 예기치 않은 결과를 반환할 수 있다는 점에 유의해야 합니다. 코드에서 이를 계획하는 것이 중요합니다.
서버/openAI.ts 돌아가서 함수를 찾습니다
isProhibitedQuery()
. Azure OpenAI에서 결과를 반환한 후 실행할 수 있는 후처리 코드의 예입니다. 생성된 SQL 쿼리에서sql
금지된 키워드가 반환되는 경우 속성을 빈 문자열로 설정합니다. 이렇게 하면 Azure OpenAI에서 예기치 않은 결과가 반환되면 SQL 쿼리가 데이터베이스에 대해 실행되지 않습니다.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)); }
참고 항목
데모 코드일 뿐입니다. 자연어를 SQL로 변환하도록 선택한 경우 특정 사용 사례를 다루는 데 필요한 다른 금지 키워드가 있을 수 있습니다. 이 기능은 유효한 SQL 쿼리만 반환되고 데이터베이스에 대해 실행되도록 주의하여 계획하고 사용해야 하는 기능입니다. 금지된 키워드 외에도 보안을 고려해야 합니다.
서버/openAI.ts 돌아가서 함수에서
getSQLFromNLP()
다음 코드의 주석 처리를 제거합니다. 파일을 저장합니다.if (isProhibitedQuery(queryData.sql)) { queryData.sql = ''; }
다음 규칙을
systemPrompt
제거하고 파일을 저장합니다.- Do not allow the SELECT query to return table names, function names, or procedure names.
브라우저로 돌아가서 데이터베이스의 모든 테이블 이름을 사용자 지정 쿼리 입력에 다시 입력하고 쿼리 실행 단추를 선택합니다.
테이블 결과가 표시 합니까? 규칙이 없는
isProhibitedQuery()
경우에도 사후 처리 코드는 해당 유형의 쿼리가 데이터베이스에 대해 실행되는 것을 금지합니다.앞에서 설명한 것처럼 비즈니스 애플리케이션에서 SQL에 자연어를 통합하는 것은 사용자에게 매우 도움이 될 수 있지만 고유한 고려 사항이 함께 제공됩니다.
장점:
사용자 친화성: 이 기능을 사용하면 기술 전문 지식 없이도 데이터베이스 상호 작용에 더 쉽게 액세스할 수 있으므로 SQL 지식의 필요성이 줄어들고 작업 속도가 향상될 수 있습니다.
생산성 향상: 비즈니스 분석가, 마케터, 임원 및 기타 비기술 사용자는 기술 전문가에 의존하지 않고도 데이터베이스에서 중요한 정보를 검색하여 효율성을 높일 수 있습니다.
광범위한 애플리케이션: 고급 언어 모델을 사용하여 다양한 사용자 및 사용 사례를 충족하도록 애플리케이션을 설계할 수 있습니다.
고려 사항:
보안: 가장 큰 문제 중 하나는 보안입니다. 사용자가 자연어를 사용하여 데이터베이스와 상호 작용할 수 있는 경우 무단 액세스 또는 악의적인 쿼리를 방지하기 위한 강력한 보안 조치가 있어야 합니다. 사용자가 데이터를 수정하지 못하도록 읽기 전용 모드를 구현하는 것이 좋습니다.
데이터 개인 정보: 특정 데이터는 중요할 수 있으며 쉽게 액세스할 수 없으므로 적절한 보호 장치와 사용자 권한이 있는지 확인해야 합니다.
정확도: 자연어 처리가 크게 향상되었지만 완벽하지는 않습니다. 사용자 쿼리를 잘못 해석하면 부정확한 결과 또는 예기치 않은 동작이 발생할 수 있습니다. 예기치 않은 결과를 처리하는 방법을 계획해야 합니다.
효율성: 자연어 쿼리에서 반환된 SQL이 효율적이라는 보장은 없습니다. 경우에 따라 사후 처리 규칙이 SQL 쿼리 문제를 감지하는 경우 Azure OpenAI에 대한 추가 호출이 필요할 수 있습니다.
교육 및 사용자 적응: 쿼리를 올바르게 작성하려면 사용자를 학습해야 합니다. SQL을 배우는 것보다 쉽지만 여전히 학습 곡선이 관련되어 있을 수 있습니다.
다음 연습으로 넘어가기 전에 고려해야 할 몇 가지 마지막 사항은 다음과 같습니다.
- "당신이 해야 한다는 것을 의미할 수 없다고 해서"가 여기에 적용된다는 것을 기억하십시오. 자연어를 SQL에 애플리케이션에 통합하기 전에 매우 신중하고 신중한 계획을 사용합니다. 잠재적인 위험을 이해하고 이를 계획하는 것이 중요합니다.
- 이러한 유형의 기술을 사용하기 전에 팀, 데이터베이스 관리자, 보안 팀, 이해 관계자 및 기타 관련 당사자와 잠재적 시나리오를 논의하여 조직에 적합한지 확인합니다. SQL에 대한 자연어가 보안, 개인 정보 보호 및 조직에 있을 수 있는 기타 요구 사항을 충족하는지 논의하는 것이 중요합니다.
- 보안은 주요 관심사이며 계획, 개발 및 배포 프로세스에 기본 제공되어야 합니다.
- SQL에 대한 자연어는 매우 강력할 수 있지만, 프롬프트에 필요한 규칙이 있고 사후 처리 기능이 포함되도록 신중하게 계획해야 합니다. 이 유형의 기능을 구현 및 테스트하고 예기치 않은 결과가 반환되는 시나리오를 고려하여 추가 시간을 계획합니다.
- Azure OpenAI를 사용하면 고객은 OpenAI와 동일한 모델을 실행하면서 Microsoft Azure의 보안 기능을 얻을 수 있습니다. Azure OpenAI는 프라이빗 네트워킹, 지역 가용성 및 책임 있는 AI 콘텐츠 필터링을 제공합니다. Azure OpenAI Service의 데이터, 개인 정보 및 보안에 대해 자세히 알아봅니다.
이제 Azure OpenAI를 사용하여 자연어를 SQL로 변환하는 방법을 알아보고 이러한 유형의 기능을 구현하는 장단점을 알아보았습니다. 다음 연습에서는 Azure OpenAI를 사용하여 전자 메일 및 SMS 메시지를 생성하는 방법을 알아봅니다.
AI: 완료 생성
SQL에 대한 자연어 기능 외에도 Azure OpenAI Service를 사용하여 전자 메일 및 SMS 메시지를 생성하여 사용자 생산성을 높이고 통신 워크플로를 간소화할 수도 있습니다. 사용자는 Azure OpenAI의 언어 생성 기능을 활용하여 "주문이 5일 지연됨"과 같은 특정 규칙을 정의할 수 있으며, 시스템은 해당 규칙에 따라 상황에 맞는 적절한 이메일 및 SMS 메시지를 자동으로 생성합니다.
이 기능은 사용자가 보내기 전에 쉽게 사용자 지정할 수 있는 신중하게 작성된 메시지 템플릿을 제공하는 점프 스타트 역할을 합니다. 그 결과 메시지를 작성하는 데 필요한 시간과 노력이 크게 감소하여 사용자가 다른 중요한 작업에 집중할 수 있습니다. 또한 Azure OpenAI의 언어 생성 기술을 자동화 워크플로에 통합하여 시스템이 미리 정의된 트리거에 대한 응답으로 메시지를 자율적으로 생성하고 보낼 수 있습니다. 이러한 수준의 자동화는 통신 프로세스를 가속화할 뿐만 아니라 다양한 시나리오에서 일관되고 정확한 메시징을 보장합니다.
이 연습에서 다음을 수행합니다.
- 다른 프롬프트를 사용하여 실험합니다.
- 프롬프트를 사용하여 전자 메일 및 SMS 메시지에 대한 완성을 생성합니다.
- AI 완성을 가능하게 하는 코드를 탐색합니다.
- 프롬프트 엔지니어링의 중요성과 프롬프트에 규칙을 포함하는 방법에 대해 알아봅니다.
전자 메일 및 SMS 메시지를 생성하는 데 사용할 수 있는 다양한 규칙을 실험해 보겠습니다.
AI 완성 기능 사용
이전 연습에서는 데이터베이스, API 및 애플리케이션을 시작했습니다. 또한 파일을 업데이트했습니다
.env
. 이러한 단계를 완료하지 않은 경우 계속하기 전에 연습의 끝에 있는 지침을 따릅니다.브라우저(http://localhost:4200)로 돌아가서 datagrid의 모든 행에서 고객에게 문의를 선택한 다음, 이메일/SMS 고객을 선택하여 메시지 생성기 화면으로 이동합니다.
Azure OpenAI를 사용하여 정의한 메시지 규칙을 이메일/SMS 메시지로 변환합니다. 다음 작업을 수행합니다.
입력에 순서가 5일 지연되는 등의 규칙을 입력하고 전자 메일/SMS 메시지 생성 단추를 선택합니다.
전자 메일에 대해 생성된 제목과 본문과 SMS에 대해 생성된 짧은 메시지가 표시됩니다.
참고 항목
Azure Communication Services는 아직 사용하도록 설정되지 않았으므로 전자 메일 또는 SMS 메시지를 보낼 수 없습니다.
브라우저에서 전자 메일/SMS 대화 상자를 닫습니다. 이제 이 기능이 작동하는 것을 살펴보았으므로 구현 방법을 살펴보겠습니다.
AI 완성 코드 탐색
팁
Visual Studio Code를 사용하는 경우 다음을 선택하여 파일을 직접 열 수 있습니다.
- Windows/Linux: Ctrl+P
- Mac: Cmd + P
그런 다음 열려는 파일의 이름을 입력합니다.
서버/apiRoutes.ts 파일을 열고 경로를 찾습니다
completeEmailSmsMessages
. 이 API는 이메일/SMS 메시지 생성 단추를 선택할 때 앱의 프런트 엔드 부분에서 호출됩니다. 본문에서 사용자 프롬프트, 회사 및 연락처 이름 값을 검색하고 서버/openAI.ts 파일의completeEmailSMSMessages()
함수에 전달합니다. 그런 다음 결과가 클라이언트에 반환됩니다.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); });
서버/openAI.ts 파일을 열고 함수를 찾습니다
completeEmailSMSMessages()
.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; }
이 함수에는 다음과 같은 기능이 있습니다.
-
systemPrompt
는 이메일 및 SMS 메시지를 생성할 수 있는 AI 도우미가 필요하도록 정의하는 데 사용됩니다. 여기에는 다음systemPrompt
이 포함됩니다.- 도우미가 메시지의 톤, 시작 및 종료 형식, SMS 메시지의 최대 길이 등을 제어하기 위해 따라야 하는 규칙입니다.
- 응답에 포함해야 하는 데이터에 대한 정보입니다. 이 경우 JSON 개체입니다.
-
userPrompt
는 최종 사용자가 전자 메일 및 SMS 메시지가 생성될 때 포함하려는 규칙 및 연락처 이름을 정의하는 데 사용됩니다. 이전에 입력한 순서가 5일 지연된 규칙이 포함userPrompt
됩니다. - 이 함수는 이전에 탐색한 함수를 호출
callOpenAI()
하여 이메일 및 SMS 완성을 생성합니다.
-
브라우저로 돌아가서 페이지를 새로 고치고, 전자 메일/SMS 고객이 있는 행에서 고객에게 문의를 선택하여 메시지 생성기 화면으로 다시 이동합니다.
메시지 생성기 입력에 다음 규칙을 입력합니다.
- 주문이 일정보다 깁니다.
- 고객에게 다시는 주문하지 말라고 말하면, 우리는 그들의 사업을 원하지 않습니다.
이메일/SMS 메시지 생성을 선택하고 메시지를 기록해 둡다.
All messages should have a friendly tone and never use inappropriate language.
시스템 프롬프트의 규칙이 사용자 프롬프트에서 음수 규칙을 재정의합니다.편집기 에서 서버/openAI.ts*로 돌아가서 함수의
All messages should have a friendly tone and never use inappropriate language.
프롬프트completeEmailSMSMessages()
에서 규칙을 제거합니다. 파일을 저장합니다.브라우저에서 이메일/SMS 메시지 생성기로 돌아가서 동일한 규칙을 다시 실행합니다.
- 주문이 일정보다 깁니다.
- 고객에게 다시는 주문하지 말라고 말하면, 우리는 그들의 사업을 원하지 않습니다.
이메일/SMS 메시지 생성을 선택하고 반환되는 메시지를 확인합니다.
이러한 시나리오에서 발생하는 일은 무엇인가요? Azure OpenAI 를 사용하는 경우 적절한 언어가 항상 사용되도록 콘텐츠 필터링을 적용할 수 있습니다. OpenAI를 사용하는 경우 시스템 프롬프트에 정의된 규칙을 사용하여 반환된 메시지가 적절한지 확인합니다.
참고 항목
이는 적절한 결과가 반환되도록 올바른 정보 및 규칙을 사용하여 프롬프트를 엔지니어링하는 것의 중요성을 보여 줍니다. 이 프로세스에 대한 자세한 내용은 프롬프트 엔지니어링 설명서 소개를 참조하세요.
변경 내용을
systemPrompt
completeEmailSMSMessages()
실행 취소하고 파일을 저장한 다음 다시 실행하지만 규칙을 사용합니다Order is ahead of schedule.
(음수 규칙은 포함하지 않음). 이번에는 예상대로 반환된 전자 메일 및 SMS 메시지가 표시됩니다.다음 연습으로 넘어가기 전에 고려해야 할 몇 가지 마지막 사항은 다음과 같습니다.
- 생성된 메시지를 검토하려면 루프에 사람이 있어야 합니다. 이 예제에서 Azure OpenAI 완성은 제안된 전자 메일 및 SMS 메시지를 반환하지만 사용자는 메시지를 보내기 전에 재정의할 수 있습니다. 전자 메일을 자동화하려는 경우 승인된 메시지를 보낼 수 있도록 일부 유형의 사용자 검토 프로세스를 사용하는 것이 중요합니다. AI를 autopilot이 아닌 부조종사로 봅니다.
- 완료는 프롬프트에 추가하는 규칙만큼만 적합합니다. 시간을 내어 프롬프트 및 반환되는 완료를 테스트합니다. 프롬프트 흐름을 사용하여 AI 애플리케이션의 프로토타입 생성, 실험, 반복 및 배포를 간소화하는 포괄적인 솔루션을 만드는 것이 좋습니다. 다른 프로젝트 관련자를 초대하여 완료도 검토합니다.
- 예기치 않은 결과가 제대로 처리되도록 하기 위해 사후 처리 코드를 포함해야 할 수 있습니다.
- 시스템 프롬프트를 사용하여 AI 도우미가 따라야 하는 규칙 및 정보를 정의합니다. 사용자 프롬프트를 사용하여 최종 사용자가 완료에 포함할 규칙 및 정보를 정의합니다.
AI: 데이터에 대한 Azure OpenAI
Azure OpenAI NLP(자연어 처리) 및 완성 기능의 통합은 사용자 생산성을 향상시킬 수 있는 상당한 잠재력을 제공합니다. AI 도우미는 적절한 프롬프트와 규칙을 활용하여 전자 메일 메시지, SMS 메시지 등과 같은 다양한 형태의 통신을 효율적으로 생성할 수 있습니다. 이 기능을 사용하면 사용자 효율성이 향상되고 워크플로가 간소화됩니다.
이 기능은 자체적으로 매우 강력하지만 사용자가 회사의 사용자 지정 데이터를 기반으로 완료를 생성해야 하는 경우가 있을 수 있습니다. 예를 들어 설치 문제가 있는 고객을 지원할 때 사용자가 탐색하기 어려울 수 있는 제품 설명서 컬렉션이 있을 수 있습니다. 또는 사용자가 필요한 답변을 읽고 가져오는 것이 어려울 수 있는 의료 혜택과 관련된 포괄적인 FAQ(질문과 대답) 집합을 유지할 수 있습니다. 이러한 경우와 다른 많은 경우에 Azure OpenAI 서비스를 사용하면 사용자 고유의 데이터를 활용하여 완성을 생성하여 사용자 질문에 보다 맞춤화되고 상황에 맞는 정확한 응답을 보장할 수 있습니다.
다음은 Azure OpenAI 설명서에서 "사용자 고유의 데이터 가져오기" 기능이 작동하는 방식에 대한 간략한 개요입니다.
참고 항목
데이터에 대한 Azure OpenAI의 주요 기능 중 하나는 모델의 출력을 향상시키는 방식으로 데이터를 검색하고 활용하는 기능입니다. Azure Open AI의 On Your Data는 Azure AI Search와 더불어 지정된 데이터 원본에서 검색할 데이터를 사용자 입력 및 제공된 대화 기록에 기반하여 결정합니다. 그런 다음 이 데이터는 확대되어 OpenAI 모델에 대한 프롬프트로 다시 제출되며, 검색된 정보는 원래 프롬프트에 추가됩니다. 검색된 데이터가 프롬프트에 추가되더라도 결과 입력은 다른 프롬프트와 마찬가지로 모델에 의해 계속 처리됩니다. 데이터가 검색되고 프롬프트가 모델에 제출되면 모델은 이 정보를 사용하여 완료를 제공합니다.
이 연습에서 다음을 수행합니다.
- Azure AI Foundry 포털을 사용하여 사용자 지정 데이터 원본을 만듭니다.
- Azure AI Foundry 포털을 사용하여 포함 모델을 배포합니다.
- 사용자 지정 문서를 업로드합니다.
- 채팅 플레이그라운드에서 채팅 세션을 시작하여 사용자 고유의 데이터를 기반으로 완료를 생성하는 실험을 시작합니다.
- Azure AI Search 및 Azure OpenAI를 사용하여 사용자 고유의 데이터를 기반으로 완료를 생성하는 코드를 살펴봅니다.
포함 모델을 배포하고 Azure AI Foundry에 사용자 지정 데이터 원본을 추가하여 시작해 보겠습니다.
Azure AI Foundry에 사용자 지정 데이터 원본 추가
Azure OpenAI Studio로 이동하여 Azure OpenAI 리소스에 액세스할 수 있는 자격 증명으로 로그인합니다.
탐색 메뉴에서 배포를 선택합니다.
도구 모음에서 모델 배포 선택 --> 배포를 선택합니다.
모델 목록에서 text-embedding-ada-002 모델을 선택하고 확인을 선택합니다.
다음 옵션을 선택합니다.
- 배포 이름: text-embedding-ada-002
- 모델 버전: 기본값
- 배포 유형: 표준
- 분당 토큰 속도 제한(천) 값을 120K로 설정합니다.
- 콘텐츠 필터: DefaultV2
- 동적 견적 사용: 사용
배포 버튼을 선택합니다.
모델을 만든 후 탐색 메뉴에서 홈을 선택하여 시작 화면으로 이동합니다.
시작 화면에서 사용자 고유의 데이터 가져오기 타일을 찾아 지금 사용해 보세요.
데이터 추가와 데이터 원본 추가를 선택합니다.
데이터 원본 선택 드롭다운에서 파일 업로드를 선택합니다.
Azure Blob Storage 리소스 선택 드롭다운에서 새 Azure Blob Storage 리소스 만들기를 선택합니다.
구독 드롭다운에서 Azure 구독을 선택합니다.
Azure Blob Storage 리소스 선택 드롭다운에서 새 Azure Blob Storage 리소스 만들기를 선택합니다.
이렇게 하면 다음 작업을 수행할 수 있는 Azure Portal로 이동합니다.
- byodstorage[Your Last Name]과 같은 스토리지 계정의 고유한 이름을 입력합니다.
- 위치와 가까운 지역을 선택합니다.
- 검토를 선택한 다음 만들기를 선택합니다.
Blob Storage 리소스가 만들어지면 Azure AI Foundry 대화 상자로 돌아가서 Azure Blob Storage 리소스 선택 드롭다운에서 새로 만든 Blob Storage 리소스를 선택합니다. 목록에 표시되지 않으면 드롭다운 옆에 있는 새로 고침 아이콘을 선택합니다.
스토리지 계정에 액세스하려면 CORS(원본 간 리소스 공유)를 설정해야 합니다. Azure AI Foundry 대화 상자에서 CORS 켭니다.
Azure AI Search 리소스 선택 드롭다운에서 새 Azure AI Search 리소스 만들기를 선택합니다.
그러면 Azure Portal로 돌아가서 다음 작업을 수행할 수 있습니다.
- BYodsearch-[Your Last Name]과 같은 AI Search 리소스의 고유한 이름을 입력합니다.
- 위치와 가까운 지역을 선택합니다.
- 가격 책정 계층 섹션에서 가격 책정 계층 변경을 선택하고 기본 및 선택을 선택합니다. 무료 계층은 지원되지 않으므로 이 자습서의 끝부분에 AI Search 리소스를 정리합니다.
- 검토를 선택한 다음 만들기를 선택합니다.
AI Search 리소스가 만들어지면 리소스 개요 페이지로 이동하여 URL 값을 로컬 파일에 복사합니다.
탐색 메뉴에서 설정 --> 선택합니다.
API 액세스 제어 페이지에서 둘 다를 선택하여 관리 ID를 사용하거나 키를 사용하여 서비스에 액세스할 수 있도록 합니다. 메시지에서 예를 선택합니다.
참고 항목
역할 할당을 추가하는 데 최대 10분이 걸릴 수 있으므로 이 연습에서는 API 키를 사용하지만 약간의 추가 작업을 통해 시스템 할당 관리 ID가 서비스에 보다 안전하게 액세스할 수 있도록 할 수 있습니다.
왼쪽 탐색 메뉴에서 키를 선택하고 기본 관리 키 값을 로컬 파일에 복사합니다. 연습의 뒷부분에서 URL 및 키 값이 필요합니다.
탐색 메뉴에서 설정 --> 선택하고 무료가 선택되어 있는지 확인합니다.
참고 항목
특정 지역에서 의미 체계 순위를 사용할 수 있는지 확인하려면 Azure 웹 사이트의 지역 별 사용 가능한 제품을 확인하여 해당 지역이 나열되어 있는지 확인합니다.
Azure AI Foundry 데이터 추가 대화 상자로 돌아가서 Azure AI Search 리소스 선택 드롭다운에서 새로 만든 검색 리소스를 선택합니다. 목록에 표시되지 않으면 드롭다운 옆에 있는 새로 고침 아이콘을 선택합니다.
인덱스 이름 값 입력에 대한 byod-search-index 값을 입력합니다.
이 검색 리소스에 벡터 검색 추가 확인란을 선택합니다.
포함 모델 선택 드롭다운에서 이전에 만든 text-embedding-ada-002 모델을 선택합니다.
파일 업로드 대화 상자에서 파일 찾아보기를 선택합니다.
프로젝트의 고객 문서 폴더(프로젝트의 루트에 있음)로 이동하고 다음 파일을 선택합니다.
- Clock A102 설치 Instructions.docx
- 회사 FAQs.docx
참고 항목
이 기능은 현재 로컬 인덱스 만들기를 위해 .txt, .md, .html, .pdf, .docx 및 .pptx 파일 형식을 지원합니다.
파일 업로드를 선택합니다. 파일은 이전에 만든 Blob Storage 리소스의 fileupload-byod-search-index 컨테이너에 업로드됩니다.
다음을 선택하여 데이터 관리 대화 상자로 이동합니다.
검색 유형 드롭다운에서 하이브리드 + 의미 체계를 선택합니다.
참고 항목
이 옵션은 키워드 및 벡터 검색을 지원합니다. 결과가 반환되면 사용자의 검색 관련성을 향상시키는 딥 러닝 모델을 사용하여 결과 집합에 보조 순위 프로세스가 적용됩니다. 의미 체계 검색에 대한 자세한 내용은 Azure AI Search 설명서에서 의미 체계 검색을 참조하세요.
크기 선택 값이 1024로 설정되어 있는지 확인합니다.
다음을 선택합니다.
Azure 리소스 인증 유형에 대해 API 키를 선택합니다. Azure AI Search 인증 설명서에서 올바른 인증 유형을 선택하는 방법에 대해 자세히 알아봅니다.
다음을 선택합니다.
세부 정보를 검토하고 저장을 선택하고 닫습니다.
이제 사용자 지정 데이터가 업로드되었으므로 데이터가 인덱싱되고 채팅 플레이그라운드에서 사용할 수 있습니다. 이 프로세스에는 몇 분 정도가 소요됩니다. 완료되면 다음 섹션으로 계속 진행합니다.
채팅 플레이그라운드에서 사용자 지정 데이터 원본 사용
Azure OpenAI Studio에서 페이지의 채팅 세션 섹션을 찾아 다음 사용자 쿼리를 입력합니다.
What safety rules are required to install a clock?
사용자 쿼리를 제출한 후 다음과 유사한 결과가 표시됩니다.
채팅 응답에서 참조 1개 섹션을 확장하고 Clock A102 설치 Instructions.docx 파일이 나열되어 있으며 이 파일을 선택하여 문서를 볼 수 있습니다.
다음 사용자 메시지를 입력합니다.
What should I do to mount the clock on the wall?
다음과 유사한 결과가 표시됩니다.
이제 회사 FAQ 문서를 실험해 보겠습니다. 사용자 쿼리 필드에 다음 텍스트를 입력합니다.
What is the company's policy on vacation time?
해당 요청에 대한 정보를 찾을 수 없습니다.
사용자 쿼리 필드에 다음 텍스트를 입력합니다.
How should I handle refund requests?
다음과 유사한 결과가 표시됩니다.
채팅 응답에서 참조 1개 섹션을 확장하고 회사 FAQs.docx 파일이 나열되고 문서를 보려면 선택할 수 있습니다.
채팅 플레이그라운드의 도구 모음에서 코드 보기를 선택합니다.
다른 언어 간에 전환하고, 엔드포인트를 보고, 엔드포인트의 키에 액세스할 수 있습니다. 샘플 코드 대화 상자 창을 닫습니다.
채팅 메시지 위에 원시 JSON 표시 토글을 켭니다. 채팅 세션은 다음과 유사한 메시지로 시작됩니다.
{ "role": "system", "content": "You are an AI assistant that helps people find information." }
이제 사용자 지정 데이터 원본을 만들고 채팅 실습에서 실험했으므로 프로젝트의 애플리케이션에서 어떻게 사용할 수 있는지 살펴보겠습니다.
애플리케이션에서 사용자 고유의 데이터 가져오기 기능 사용
VS Code에서 프로젝트로 돌아가서 .env 파일을 엽니다. AI Services 엔드포인트, 키 및 인덱스 이름으로 다음 값을 업데이트합니다. 이 연습의 앞부분에서 엔드포인트와 키를 로컬 파일에 복사했습니다.
AZURE_AI_SEARCH_ENDPOINT=<AI_SERVICES_ENDPOINT_VALUE> AZURE_AI_SEARCH_KEY=<AI_SERVICES_KEY_VALUE> AZURE_AI_SEARCH_INDEX=byod-search-index
이전 연습에서는 데이터베이스, API 및 애플리케이션을 시작했습니다. 또한 파일을 업데이트했습니다
.env
. 이러한 단계를 완료하지 않은 경우 계속하기 전에 이전 연습의 끝에 있는 지침을 따릅니다.애플리케이션이 브라우저에 로드되면 애플리케이션의 오른쪽 위에 있는 채팅 도움말 아이콘을 선택합니다.
채팅 대화 상자에 다음 텍스트가 표시됩니다.
How should I handle a company refund request?
도움말 가져오기 단추를 선택합니다. 이전에 Azure OpenAI Studio에서 업로드한 회사 FAQs.docx 문서에서 반환된 결과가 표시됩니다. 문서를 읽으려는 경우 프로젝트의 루트에 있는 고객 문서 폴더에서 찾을 수 있습니다.
텍스트를 다음으로 변경하고 도움말 가져오기 단추를 선택합니다.
What safety rules are required to install a clock?
이전에 Azure OpenAI Studio에서 업로드한 Clock A102 설치 Instructions.docx 문서에서 반환된 결과가 표시됩니다. 이 문서는 프로젝트의 루트에 있는 고객 문서 폴더에서도 사용할 수 있습니다.
코드 탐색
팁
Visual Studio Code를 사용하는 경우 다음을 선택하여 파일을 직접 열 수 있습니다.
- Windows/Linux: Ctrl+P
- Mac: Cmd + P
그런 다음 열려는 파일의 이름을 입력합니다.
Visual Studio Code에서 프로젝트 소스 코드로 돌아갑니다.
서버/apiRoutes.ts 파일을 열고 경로를 찾습니다
completeBYOD
. 이 API는 채팅 도움말 대화 상자에서 도움말 가져오기 단추를 선택할 때 호출됩니다. 요청 본문에서 사용자 프롬프트를 검색하고 서버/openAI.ts 파일의completeBYOD()
함수에 전달합니다. 그런 다음 결과가 클라이언트에 반환됩니다.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); });
서버/openAI.ts 파일을 열고 함수를 찾습니다
completeBYOD()
.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); }
이 함수에는 다음과 같은 기능이 있습니다.
- 매개 변수에는
userPrompt
사용자가 채팅 도움말 대화 상자에 입력한 정보가 포함됩니다. - 변수는
systemPrompt
사람들이 정보를 찾는 데 도움이 되도록 설계된 AI 도우미가 사용되도록 정의합니다. -
callOpenAI()
는 Azure OpenAI API를 호출하고 결과를 반환하는 데 사용됩니다. 다음 매개 변수뿐만 아니라 값과systemPrompt
값을 전달합니다userPrompt
.-
temperature
- 응답에 포함할 창의성의 양입니다. 이 경우 사용자는 일관된(덜 창의적인) 답변이 필요하므로 값은 0으로 설정됩니다. -
useBYOD
- Azure OpenAI와 함께 AI Search를 사용할지 여부를 나타내는 부울 값입니다. 이 경우 AI Search 기능이 사용되도록 설정true
됩니다.
-
- 매개 변수에는
함수는
callOpenAI()
호출할 OpenAI 함수를 결정하는 데 사용되는 매개 변수를 허용useBYOD
합니다. 이 경우 함수가useBYOD
호출되도록true
설정합니다getAzureOpenAIBYODCompletion()
.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); }
getAzureOpenAIBYODCompletion()
서버/openAI.ts 함수를 찾습니다. 앞에서 검사한 함수와 매우 유사getAzureOpenAICompletion()
하지만 Azure OpenAI에서 사용할 수 있는 "데이터의 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() ?? ''; }
함수에서 다음 기능을 확인합니다
getAzureOpenAIBYODCompletion()
.-
dataSources
이 연습의key
endpoint
앞부분에서 파일에 추가index_name
된 값과.env
AI Search 리소스를 포함하는 속성이 만들어집니다. - 함수는
createAzureOpenAICompletion()
,systemPrompt
및userPrompt
temperature
값을 사용하여dataSources
호출됩니다. 이 함수는 Azure OpenAI API를 호출하고 결과를 반환하는 데 사용됩니다. - 응답이 반환되면 문서 인용이 콘솔에 기록됩니다. 그러면 완료 메시지 콘텐츠가 호출자에게 반환됩니다.
-
다음 연습으로 넘어가기 전에 고려해야 할 몇 가지 마지막 사항은 다음과 같습니다.
- 샘플 애플리케이션은 Azure AI Search에서 단일 인덱스 사용 Azure OpenAI에서 여러 인덱스 및 데이터 원본을 사용할 수 있습니다.
dataSources
필요에 따라 여러 데이터 원본을getAzureOpenAIBYODCompletion()
포함하도록 함수의 속성을 업데이트할 수 있습니다. - 보안은 이러한 유형의 시나리오를 사용하여 신중하게 평가해야 합니다. 사용자는 액세스할 수 없는 문서에서 질문을 하고 결과를 얻을 수 없습니다.
- 샘플 애플리케이션은 Azure AI Search에서 단일 인덱스 사용 Azure OpenAI에서 여러 인덱스 및 데이터 원본을 사용할 수 있습니다.
Azure OpenAI, 프롬프트, 완료 및 사용자 고유의 데이터를 사용하는 방법에 대해 알아보았으므로 이제 다음 연습으로 이동하여 통신 기능을 사용하여 애플리케이션을 개선하는 방법을 알아보겠습니다. Azure OpenAI에 대해 자세히 알아보려면 Azure OpenAI 서비스 교육 콘텐츠 시작을 확인하세요. Azure OpenAI에서 사용자 고유의 데이터를 사용하는 방법에 대한 추가 정보는 데이터 설명서의 Azure OpenAI에서 찾을 수 있습니다.
통신: Azure Communication Services 리소스 만들기
효과적인 통신은 성공적인 사용자 지정 비즈니스 애플리케이션에 필수적입니다. ACS(Azure Communication Services)를 사용하여 전화 통화, 라이브 채팅, 오디오/영상 통화, 이메일 및 SMS 메시징과 같은 기능을 애플리케이션에 추가할 수 있습니다. 앞서 Azure OpenAI가 전자 메일 및 SMS 메시지에 대한 완성을 생성하는 방법을 알아보았습니다. 이제 메시지를 보내는 방법을 알아봅니다. ACS와 OpenAI는 함께 통신을 간소화하고 상호 작용을 개선하며 비즈니스 생산성을 향상시켜 애플리케이션을 향상시킬 수 있습니다.
이 연습에서 다음을 수행합니다.
- ACS(Azure Communication Services) 리소스를 만듭니다.
- 통화 및 SMS 기능이 있는 무료 전화 번호를 추가합니다.
- 전자 메일 도메인을 연결합니다.
- 프로젝트의 .env 파일을 ACS 리소스의 값으로 업데이트합니다.
Azure Communication Services 리소스 만들기
브라우저에서 Azure Portal 을 방문하여 아직 로그인하지 않은 경우 로그인합니다.
페이지 맨 위에 있는 검색 창에 통신 서비스를 입력하고 표시되는 옵션에서 Communication Services를 선택합니다.
도구 모음에서 만들기를 선택합니다.
다음 작업을 수행합니다.
- Azure 구독을 선택합니다.
- 사용할 리소스 그룹을 선택합니다(없는 경우 새 리소스 그룹 만들기).
- ACS 리소스 이름을 입력합니다. 고유한 값이어야 합니다.
- 데이터 위치를 선택합니다.
검토 + 만들기를 선택한 다음 만들기를 선택합니다.
새 Azure Communication Services 리소스를 성공적으로 만들었습니다. 다음으로 전화 통화 및 SMS 기능을 사용하도록 설정합니다. 또한 전자 메일 도메인을 리소스에 연결합니다.
전화 통화 및 SMS 기능 사용
전화 번호를 추가하고 전화 번호에 통화 기능이 사용하도록 설정되어 있는지 확인합니다. 이 전화 번호를 사용하여 앱에서 전화를 겁니다.
리소스 메뉴에서 전화 통신 및 SMS --> 선택합니다.
도구 모음에서 + 가져오기를 선택하거나 숫자 가져오기 단추를 선택하고 다음 정보를 입력합니다.
-
국가 또는 지역:
United States
-
숫자 유형:
Toll-free
참고 항목
무료 번호를 만들려면 Azure 구독에 신용 카드가 필요합니다. 파일에 카드가 없는 경우 전화 번호 추가를 건너뛰고 전자 메일 도메인을 연결하는 연습의 다음 섹션으로 이동하세요. 앱을 계속 사용할 수 있지만 전화 번호로 전화를 걸 수는 없습니다.
- 번호: 나열된 전화 번호 중 하나에 대해 카트에 추가를 선택합니다.
-
국가 또는 지역:
다음을 선택하고 전화 번호 세부 정보를 검토한 다음 지금 구입을 선택합니다.
참고 항목
이제 미국 및 캐나다에서 무료 번호에 대한 SMS 확인이 필수입니다. SMS 메시징을 사용하도록 설정하려면 전화 번호 구매 후 확인을 제출해야 합니다. 이 자습서는 해당 프로세스를 거치지 않지만 리소스 메뉴에서 전화 통신 및 SMS --> 선택하고 필요한 유효성 검사 설명서를 추가할 수 있습니다.
전화 번호가 만들어지면 이를 선택하여 기능 패널로 연결합니다 . 다음 값이 설정되어 있는지 확인합니다(기본적으로 설정해야 합니다).
-
통화 섹션에서 .를 선택합니다
Make calls
. -
SMS 섹션에서 .를 선택합니다
Send and receive SMS
. - 저장을 선택합니다.
-
통화 섹션에서 .를 선택합니다
나중에 사용할 수 있는 파일로 전화 번호 값을 복사합니다. 전화 번호는 다음과 같은 일반적인 패턴을
+12345678900
따라야 합니다.
전자 메일 도메인 연결
다음 작업을 수행하여 전자 메일을 보낼 수 있도록 ACS 리소스에 연결된 전자 메일 도메인을 만듭니다. 앱에서 전자 메일을 보내는 데 사용됩니다.
- 리소스 메뉴에서 전자 메일 -->을 선택합니다.
- 도구 모음에서 연결 도메인을 선택합니다.
- 구독 및 리소스 그룹을 선택합니다.
-
전자 메일 서비스 드롭다운에서 .를 선택합니다
Add an email service
. - 전자 메일 서비스에 다음과 같은
acs-demo-email-service
이름을 지정합니다. - 검토 + 만들기를 선택한 다음 만들기를 선택합니다.
- 배포가 완료되면 선택하고
Go to resource
무료 Azure 하위 도메인을 추가하도록 선택합니다1-click add
. - 하위 도메인이 추가된 후(배포하는 데 몇 분 정도 소요됨) 선택합니다.
- AzureManagedDomain 화면이 표시되면 리소스 메뉴에서 메일 서비스 --> 선택합니다.
- MailFrom 값을 파일에 복사합니다. 나중에 .env 파일을 업데이트할 때 사용합니다.
- Azure Communication Services 리소스로 돌아가서 리소스 메뉴에서 이메일 -->을 선택합니다.
- 이전 단계의
Add domain
값을 선택하고MailFrom
입력합니다(올바른 구독, 리소스 그룹 및 전자 메일 서비스를 선택했는지 확인).Connect
단추를 선택합니다.
.env
파일 업데이트
이제 ACS 전화 번호(통화 및 SMS 사용) 및 전자 메일 도메인이 준비되었으므로 프로젝트의 .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>
ACS_CONNECTION_STRING
connection string
: ACS 리소스의 키 섹션에 있는 값입니다.ACS_PHONE_NUMBER
: 무료 번호를 값에ACS_PHONE_NUMBER
할당합니다.ACS_EMAIL_ADDRESS
: 전자 메일 "MailTo" 주소 값을 할당합니다.CUSTOMER_EMAIL_ADDRESS
: 앱에서 전자 메일을 보내려는 전자 메일 주소를 할당합니다(앱 데이터베이스의 고객 데이터는 샘플 데이터일 뿐이므로). 개인 전자 메일 주소를 사용할 수 있습니다.CUSTOMER_PHONE_NUMBER
: 다른 국가에서 SMS 메시지를 보내는 데 필요한 추가 확인으로 인해 미국 기반 전화 번호(오늘 기준)를 제공해야 합니다. 미국 기반 번호가 없으면 비워 둘 수 있습니다.
애플리케이션 및 API 서버 시작/다시 시작
이 시점까지 완료한 연습에 따라 다음 단계 중 하나를 수행합니다.
이전 연습에서 데이터베이스, API 서버 및 웹 서버를 시작한 경우 API 서버 및 웹 서버를 중지하고 다시 시작하여 .env 파일 변경 내용을 선택해야 합니다. 데이터베이스를 실행 상태로 둘 수 있습니다.
API 서버 및 웹 서버를 실행하는 터미널 창을 찾아 Ctrl+C를 눌러 중지합니다. 각 터미널 창에 입력하고
npm start
Enter 키를 눌러 다시 시작합니다. 다음 연습을 계속합니다.데이터베이스, API 서버 및 웹 서버를 아직 시작하지 않은 경우 다음 단계를 완료합니다.
다음 단계에서는 Visual Studio Code에서 세 개의 터미널 창을 만듭니다.
Visual Studio Code 파일 목록에서 .env 파일을 마우스 오른쪽 단추로 클릭하고 통합 터미널에서 열기를 선택합니다. 계속하기 전에 터미널이 프로젝트의 루트인 openai-acs-msgraph 에 있는지 확인합니다.
다음 옵션 중 하나를 선택하여 PostgreSQL 데이터베이스를 시작합니다.
Docker Desktop을 설치하고 실행 중인 경우 터미널 창에서 실행하고
docker-compose up
Enter 키를 누릅니다.Podman-compose가 설치되고 실행 중인 Podman이 있는 경우 터미널 창에서 실행하고
podman-compose up
Enter 키를 누릅니다.Docker Desktop, Podman, nerdctl 또는 설치한 다른 컨테이너 런타임을 사용하여 PostgreSQL 컨테이너를 직접 실행하려면 터미널 창에서 다음 명령을 실행합니다.
Mac, Linux 또는 Linux용 Windows 하위 시스템(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
PowerShell이 있는 Windows:
[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
데이터베이스 컨테이너가 시작되면 Visual Studio Code +의 아이콘을 눌러 두 번째 터미널 창을 만듭니다.
cd
서버/typescript 폴더로 이동하고 다음 명령을 실행하여 종속성을 설치하고 API 서버를 시작합니다.npm install
npm start
+ Visual Studio Code 터미널 도구 모음에서 아이콘을 다시 눌러 세 번째 터미널 창을 만듭니다.
cd
클라이언트 폴더에 다음 명령을 실행하여 종속성을 설치하고 웹 서버를 시작합니다.npm install
npm start
브라우저가 시작되고 이 브라우저로 이동 http://localhost:4200됩니다.
통신: 전화 걸기
Azure Communication Services의 전화 통화 기능을 사용자 지정 LOB(기간 업무) 애플리케이션에 통합하면 비즈니스 및 사용자에게 다음과 같은 몇 가지 주요 이점이 제공됩니다.
- LOB 애플리케이션 내에서 직접 직원, 고객 및 파트너 간의 원활하고 실시간 통신을 가능하게 하므로 여러 플랫폼 또는 디바이스 간에 전환할 필요가 없습니다.
- 사용자 환경을 향상시키고 전반적인 운영 효율성을 향상시킵니다.
- 사용자가 관련 지원 팀 또는 실무 전문가와 빠르고 쉽게 연결할 수 있으므로 신속한 문제 해결을 지원합니다.
이 연습에서 다음을 수행합니다.
- 애플리케이션에서 전화 통화 기능을 탐색합니다.
- 코드를 연습하여 전화 통화 기능이 빌드되는 방법을 알아봅니다.
전화 통화 기능 사용
이전 연습에서는 ACS(Azure Communication Services) 리소스를 만들고 데이터베이스, 웹 서버 및 API 서버를 시작했습니다. 또한 .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>
계속하기 전에 이전 연습을 완료했는지 확인합니다.
브라우저()http://localhost:4200로 돌아가서 datagrid를 찾은 다음 첫 번째 행에서 고객에 문의를 선택합니다.
전화 통화 구성 요소가 헤더에 추가됩니다. 전화할 전화 번호를 입력하고(+로 시작하고 국가 코드를 포함하는지 확인) 통화를 선택합니다. 마이크에 대한 액세스를 허용하라는 메시지가 표시됩니다.
전화 걸기를 선택하여 통화를 종료합니다. 닫기를 선택하여 전화 통화 구성 요소를 닫습니다.
전화 통화 코드 탐색
팁
Visual Studio Code를 사용하는 경우 다음을 선택하여 파일을 직접 열 수 있습니다.
- Windows/Linux: Ctrl+P
- Mac: Cmd + P
그런 다음 열려는 파일의 이름을 입력합니다.
customers-list.component.ts 파일을 엽니다. 파일의 전체 경로는 클라이언트/src/app/customers-list/customers-list.component.ts.
openCallDialog()
이벤트 버스를 사용하여 메시지와 고객 전화 번호를 보냅니CustomerCall
다.openCallDialog(data: Phone) { this.eventBus.emit({ name: Events.CustomerCall, value: data }); }
참고 항목
이벤트 버스 코드는 더 자세히 탐색하려는 경우 eventbus.service.ts 파일에서 찾을 수 있습니다. 파일의 전체 경로는 클라이언트/src/app/core/eventbus.service.ts.
헤더 구성 요소의
ngOnInit()
함수는 이벤트 버스에서 보낸 이벤트를 구독CustomerCall
하고 전화 통화 구성 요소를 표시합니다. 이 코드 는 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 }) ); }
phone-call.component.ts 엽니다. 잠시 시간을 내어 코드를 지수합니다. 파일의 전체 경로는 클라이언트/src/app/phone-call/phone-call.component.ts. 다음 주요 기능에 유의하세요.
- 에서 함수
acsService.getAcsToken()
를 호출하여 Azure Communication Services 액세스 토큰을ngOnInit()
검색합니다. - 페이지에 "전화 걸기"를 추가합니다. 머리글에서 전화 번호 입력을 클릭하여 다이얼러를 볼 수 있습니다.
- 각각 및
startCall()
함수를 사용하여 호출을endCall()
시작하고 종료합니다.
- 에서 함수
전화를 걸 코드를 살펴보기 전에 ACS 액세스 토큰을 검색하는 방법과 전화 통화 개체를 만드는 방법을 살펴보겠습니다. phone-call.component.ts 함수를
ngOnInit()
찾습니다.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); }) ); } }
이 함수는 다음의 작업을 수행합니다.
- 함수를 호출하여 ACS userId 및 액세스 토큰을 검색합니다
acsService.getAcsToken()
. - 액세스 토큰이 검색되면 코드는 다음 작업을 수행합니다.
- 액세스 토큰의
CallClient
새 인스턴스를 만들고AzureCommunicationTokenCredential
사용합니다. - 및 개체를
CallAgent
사용하는 새 인스턴스를CallClient
만듭니AzureCommunicationTokenCredential
다. 나중에 호출을 시작하고 종료하는 데 사용되는 것을CallAgent
볼 수 있습니다.
- 액세스 토큰의
- 함수를 호출하여 ACS userId 및 액세스 토큰을 검색합니다
acs.services.ts 열고 함수를 찾습니다
getAcsToken()
. 파일의 전체 경로는 클라이언트/src/app/core/acs.service.ts. 이 함수는 API 서버에서 노출하는 경로에/acstoken
대한 HTTP GET 요청을 만듭니다.getAcsToken(): Observable<AcsUser> { return this.http.get<AcsUser>(this.apiUrl + 'acstoken') .pipe( catchError(this.handleError) ); }
명명된
createACSToken()
API 서버 함수는 userId 및 액세스 토큰을 검색하고 클라이언트에 반환합니다. 서버/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 }; }
이 함수는 다음의 작업을 수행합니다.
- ACS 값을 사용할 수 있는지 확인합니다
connectionString
. 그렇지 않은 경우 빈userId
token
개체와 . - 새 인스턴스
CommunicationIdentityClient
를 만들고 값을 전달합니다connectionString
. - "voip" 범위를 사용하여
tokenClient.createUserAndToken()
새 사용자 및 토큰을 만듭니다. - 값과
userId
값을 포함하는 개체를token
반환합니다.
- ACS 값을 사용할 수 있는지 확인합니다
이제 userId 및 토큰을 검색하는 방법을 살펴보았으므로 다시 돌아가 함수를
phone-call.component.ts
startCall()
찾습니다.이 함수는 전화 통화 구성 요소에서 통화를 선택할 때 호출됩니다. 앞에서 언급한 개체를
CallAgent
사용하여 호출을 시작합니다. 이 함수는callAgent.startCall()
호출할 번호와 전화를 걸 때 사용되는 ACS 전화 번호를 나타내는 개체를 허용합니다.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; } }); }
전화
endCall()
통화 구성 요소에서 끊기를 선택하면 함수가 호출됩니다.endCall() { if (this.call) { this.call.hangUp({ forEveryone: true }); this.call = undefined; this.inCall = false; } else { this.hangup.emit(); } }
호출이 진행 중인 경우 호출을
call.hangUp()
종료하기 위해 함수가 호출됩니다. 통화가 진행 중hangup
이 아니면 헤더 부모 구성 요소로 이벤트를 내보내 전화 통화 구성 요소를 숨깁니다.다음 연습으로 이동하기 전에 이 연습에서 다루는 주요 개념을 검토해 보겠습니다.
- ACS userId 및 액세스 토큰은 함수를 사용하여
acsService.createUserAndToken()
API 서버에서 검색됩니다. - 토큰은 및
CallClient
개체를CallAgent
만드는 데 사용됩니다. - 개체는
CallAgent
각각 및callAgent.startCall()
함수를 호출하여 호출을callAgent.hangUp()
시작하고 종료하는 데 사용됩니다.
- ACS userId 및 액세스 토큰은 함수를 사용하여
이제 전화 통화를 애플리케이션에 통합하는 방법을 배웠으므로 이제 Azure Communication Services를 사용하여 전자 메일 및 SMS 메시지를 보내는 데 초점을 맞추겠습니다.
통신: 전자 메일 및 SMS 메시지 보내기
전화 통화 외에도 Azure Communication Services는 전자 메일 및 SMS 메시지를 보낼 수 있습니다. 이는 애플리케이션에서 직접 고객 또는 다른 사용자에게 메시지를 보내려는 경우에 유용할 수 있습니다.
이 연습에서 다음을 수행합니다.
- 애플리케이션에서 전자 메일 및 SMS 메시지를 보내는 방법을 알아보세요.
- 코드를 연습하여 전자 메일 및 SMS 기능이 구현되는 방법을 알아봅니다.
전자 메일 및 SMS 기능 사용
이전 연습에서는 ACS(Azure Communication Services) 리소스를 만들고 데이터베이스, 웹 서버 및 API 서버를 시작했습니다. 또한 .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>
계속하기 전에 연습을 완료했는지 확인합니다.
브라우저(http://localhost:4200)로 돌아가서 고객 문의를 선택한 다음, 첫 번째 행에서 이메일/SMS 고객을 선택합니다.
전자 메일/SMS 탭을 선택하고 다음 작업을 수행합니다.
- 전자 메일 제목 및 본문을 입력하고 전자 메일 보내기 단추를 선택합니다.
- SMS 메시지를 입력하고 SMS 보내기 단추를 선택합니다.
참고 항목
이제 미국 및 캐나다에서 무료 번호에 대한 SMS 확인이 필수입니다. SMS 메시징을 사용하도록 설정하려면 전화 번호 구매 후 확인을 제출해야 합니다. 이 자습서는 해당 프로세스를 거치지 않지만 Azure Portal의 Azure Communication Services 리소스에서 전화 통신 및 SMS --> 선택하고 필요한 유효성 검사 설명서를 추가할 수 있습니다.
전자 메일 및 SMS 메시지를 받았는지 확인합니다. SMS 기능은 이전 메모에 언급된 규정 문서를 제출한 경우에만 작동합니다. 미리 알림으로 전자 메일 메시지는 정의된
CUSTOMER_EMAIL_ADDRESS
값으로 전송되고 SMS 메시지는 .env 파일에 정의된CUSTOMER_PHONE_NUMBER
값으로 전송됩니다. SMS 메시지에 사용할 미국 기반 전화 번호를 제공할 수 없는 경우 해당 단계를 건너뛸 수 있습니다.참고 항목
.env 파일에서 정의
CUSTOMER_EMAIL_ADDRESS
한 주소의 받은 편지함에 전자 메일 메시지가 표시되지 않으면 스팸 폴더를 확인합니다.
전자 메일 코드 탐색
팁
Visual Studio Code를 사용하는 경우 다음을 선택하여 파일을 직접 열 수 있습니다.
- Windows/Linux: Ctrl+P
- Mac: Cmd + P
그런 다음 열려는 파일의 이름을 입력합니다.
customers-list.component.ts 파일을 엽니다. 파일의 전체 경로는 클라이언트/src/app/customers-list/customers-list.component.ts.
Datagrid에서 고객 문의를 선택한 후 이메일/SMS 고객을 선택하면 구성 요소에 대화 상자가
customer-list
표시됩니다. 이 작업은 customer-list.component.tsopenEmailSmsDialog()
의해 처리됩니다.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.'); } }
이 함수는
openEmailSmsDialog()
다음 작업을 수행합니다.- datagrid의
data
행을 나타내는 개체에 및phone
속성이 포함되어 있는지 확인합니다email
. 이 경우 대화 상자에 전달할 정보가 포함된 개체를 만듭니다dialogData
. -
EmailSmsDialogComponent
대화 상자를 열고 개체를dialogData
전달합니다. - 대화 상자의
afterClosed()
이벤트를 구독합니다. 이 이벤트는 대화 상자가 닫혀 있을 때 발생합니다. 개체는response
대화 상자에 입력한 정보를 포함합니다.
- datagrid의
email-sms-dialog.component.ts 파일을 엽니다. 파일의 전체 경로는 클라이언트/src/app/email-sms-dialog/email-sms-dialog.component.ts.
함수를 찾습니다.
sendEmail()
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 } }
이 함수는
sendEmail()
다음 작업을 수행합니다.- 기능 플래그가
acsEmailEnabled
.로 설정되어 있는지 확인합니다true
. 이 플래그는 환경 변수에ACS_EMAIL_ADDRESS
할당된 값이 있는지 확인합니다. - true이면
acsEmailEnabled
함수가acsService.sendEmail()
호출되고 전자 메일 제목, 본문, 고객 이름 및 고객 전자 메일 주소가 전달됩니다. 데이터베이스에 샘플 데이터가CUSTOMER_EMAIL_ADDRESS
포함되어 있으므로 환경 변수가 대신 사용됩니다this.data.email
. 실제 애플리케이션에서 값이this.data.email
사용됩니다. - 서비스의 함수를
sendEmail()
구독합니다acsService
. 이 함수는 클라이언트 쪽 서비스의 응답을 포함하는 관찰 가능한 RxJS를 반환합니다. - 전자 메일이 성공적으로
emailSent
전송된 경우 속성은 .로true
설정됩니다.
- 기능 플래그가
더 나은 코드 캡슐화 및 재사용을 제공하기 위해 acs.service.ts 같은 클라이언트 쪽 서비스가 애플리케이션 전체에서 사용됩니다. 이렇게 하면 모든 ACS 기능을 단일 위치로 통합할 수 있습니다.
acs.service.ts 열고 함수를 찾습니다
sendEmail()
. 파일의 전체 경로는 클라이언트/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) ); }
함수
sendEmail()
는AcsService
다음 작업을 수행합니다.- 함수를
http.post()
호출하고 전자 메일 제목, 메시지, 고객 이름 및 고객 전자 메일 주소를 전달합니다. 이 함수는http.post()
API 호출의 응답을 포함하는 관찰 가능한 RxJS를 반환합니다. - RxJS 연산자를 사용하여 함수에서
http.post()
반환된 오류를 처리합니다catchError
.
- 함수를
이제 애플리케이션이 ACS 전자 메일 기능과 상호 작용하는 방법을 살펴보겠습니다. acs.ts 파일을 열고 함수를 찾습니다
sendEmail()
. 파일의 전체 경로는 서버/typescript/acs.ts.이 함수는
sendEmail()
다음 작업을 수행합니다.새
EmailClient
개체를 만들고 ACS 연결 문자열 전달합니다(이 값은 환경 변수에서ACS_CONNECTION_STRING
검색됨).const emailClient = new EmailClient(connectionString);
새
EmailMessage
개체를 만들고 보낸 사람, 제목, 메시지 및 받는 사람 정보를 전달합니다.const msgObject: EmailMessage = { senderAddress: process.env.ACS_EMAIL_ADDRESS as string, content: { subject: subject, plainText: message, }, recipients: { to: [ { address: customerEmailAddress, displayName: customerName, }, ], }, };
함수를 사용하여
emailClient.beginSend()
이메일을 보내고 응답을 반환합니다. 이 예제에서는 함수가 한 명의 받는 사람에게만 전송되지만 함수를beginSend()
사용하여 여러 받는 사람에게도 보낼 수 있습니다.const poller = await emailClient.beginSend(msgObject);
개체가
poller
완료되었음을 알리기 위해 대기하고 호출자에게 응답을 보냅니다.
SMS 코드 탐색
이전에 연 email-sms-dialog.component.ts 파일로 돌아갑니다. 파일의 전체 경로는 클라이언트/src/app/email-sms-dialog/email-sms-dialog.component.ts.
함수를 찾습니다.
sendSms()
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; } }
이 함수는
sendSMS()
다음 작업을 수행합니다.- 기능 플래그가
acsPhoneEnabled
.로 설정되어 있는지 확인합니다true
. 이 플래그는 환경 변수에ACS_PHONE_NUMBER
할당된 값이 있는지 확인합니다. - true이면
acsPhoneEnabled
함수가acsService.SendSms()
호출되고 SMS 메시지 및 고객 전화 번호가 전달됩니다. 데이터베이스에 샘플 데이터가CUSTOMER_PHONE_NUMBER
포함되어 있으므로 환경 변수가 대신 사용됩니다this.data.customerPhoneNumber
. 실제 애플리케이션에서 값이this.data.customerPhoneNumber
사용됩니다. - 서비스의 함수를
sendSms()
구독합니다acsService
. 이 함수는 클라이언트 쪽 서비스의 응답을 포함하는 관찰 가능한 RxJS를 반환합니다. - SMS 메시지가 성공적으로 전송된 경우 속성을
smsSent
.로 설정합니다true
.
- 기능 플래그가
acs.service.ts 열고 함수를 찾습니다
sendSms()
. 파일의 전체 경로는 클라이언트/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) ); }
이 함수는
sendSms()
다음 작업을 수행합니다.- 함수를
http.post()
호출하고 메시지 및 고객 전화 번호를 전달합니다. 이 함수는http.post()
API 호출의 응답을 포함하는 관찰 가능한 RxJS를 반환합니다. - RxJS 연산자를 사용하여 함수에서
http.post()
반환된 오류를 처리합니다catchError
.
- 함수를
마지막으로 애플리케이션이 ACS SMS 기능과 상호 작용하는 방법을 살펴보겠습니다. acs.ts 파일을 엽니다. 파일의 전체 경로는 서버/typescript/acs.ts 함수를 찾습니다
sendSms()
.이 함수는
sendSms()
다음 작업을 수행합니다.새
SmsClient
개체를 만들고 ACS 연결 문자열 전달합니다(이 값은 환경 변수에서ACS_CONNECTION_STRING
검색됨).const smsClient = new SmsClient(connectionString);
함수를
smsClient.send()
호출하고 ACS 전화 번호(from
), 고객 전화 번호(to
) 및 SMS 메시지를 전달합니다.const sendResults = await smsClient.send({ from: process.env.ACS_PHONE_NUMBER as string, to: [customerPhoneNumber], message: message }); return sendResults;
호출자에 대한 응답을 반환합니다.
다음 문서에서 ACS 전자 메일 및 SMS 기능에 대해 자세히 알아볼 수 있습니다.
다음 연습으로 이동하기 전에 이 연습에서 다루는 주요 개념을 검토해 보겠습니다.
- acs.service.ts 파일은 클라이언트 쪽 애플리케이션에서 사용하는 ACS 전자 메일 및 SMS 기능을 캡슐화합니다. 서버에 대한 API 호출을 처리하고 호출자에게 응답을 반환합니다.
- 서버 쪽 API는 ACS
EmailClient
및SmsClient
개체를 사용하여 전자 메일 및 SMS 메시지를 보냅니다.
전자 메일 및 SMS 메시지를 보내는 방법을 알아보았으므로 이제 조직 데이터를 애플리케이션에 통합하는 데 초점을 맞추겠습니다.
조직 데이터: Microsoft Entra ID 앱 등록 만들기
조직 데이터(전자 메일, 파일, 채팅 및 일정 이벤트)를 사용자 지정 애플리케이션에 직접 통합하여 사용자 생산성을 향상시킵니다. Microsoft Graph API 및 Microsoft Entra ID를 사용하면 앱 내에서 관련 데이터를 원활하게 검색하고 표시할 수 있으므로 사용자가 컨텍스트를 전환할 필요가 줄어듭니다. 고객에게 전송된 전자 메일을 참조하거나 Teams 메시지를 검토하거나 파일에 액세스하는 경우 사용자는 앱을 종료하지 않고도 필요한 정보를 빠르게 찾을 수 있으므로 의사 결정 프로세스를 간소화할 수 있습니다.
이 연습에서 다음을 수행합니다.
- Microsoft Graph가 조직 데이터에 액세스하여 앱으로 가져올 수 있도록 Microsoft Entra ID 앱 등록을 만듭니다.
-
team
특정 채널로 채팅 메시지를 보내는 데 필요한 Microsoft Teams에서 ID를 찾아서 찾channel
습니다. - 프로젝트의 .env 파일을 Microsoft Entra ID 앱 등록의 값으로 업데이트합니다.
Microsoft Entra ID 앱 등록 만들기
Azure Portal로 이동하여 Microsoft Entra ID를 선택합니다.
관리 --> 다음 + 새 등록을 선택합니다.
아래와 같이 새 앱 등록 양식 세부 정보를 입력하고 등록을 선택합니다.
- 이름: microsoft-graph-app
- 지원되는 계정 유형: 모든 조직 디렉터리의 계정(모든 Microsoft Entra ID 테넌트 - 다중 테넌트)
- 리디렉션 URI:
- SPA(단일 페이지 애플리케이션)를 선택하고 리디렉션 URI 필드에 입력
http://localhost:4200
합니다.
- SPA(단일 페이지 애플리케이션)를 선택하고 리디렉션 URI 필드에 입력
- 등록을 선택하여 앱 등록을 만듭니다.
리소스 메뉴에서 개요를 선택하고 값을 클립보드에 복사
Application (client) ID
합니다.
프로젝트의 .env 파일 업데이트
편집기에서 .env 파일을 열고 값을 할당
Application (client) ID
합니다ENTRAID_CLIENT_ID
.ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE>
앱에서 Teams 채널로 메시지를 보낼 수 있도록 하려면 Microsoft 365 개발 테넌트 계정을 사용하여 Microsoft Teams에 로그인합니다(자습서의 사전 준비에서 설명).
로그인한 후 팀을 확장하고 앱에서 메시지를 보낼 채널을 찾습니다. 예를 들어 회사 팀 및 일반 채널(또는 사용하려는 팀/채널)을 선택할 수 있습니다.
팀 헤더에서 세 개의 점(...)을 클릭하고 팀에 대한 링크 가져오기를 선택합니다.
팝업 창에 표시되는 링크에서 팀 ID는 다음 문자와 숫자
team/
의 문자열입니다. 예를 들어 링크 "https://teams.microsoft.com/l/team/19%3ae9b9.../"에서 팀 ID는 19%3ae9b9... 다음/
문자까지팀 ID를 복사하여 .env 파일에 할당합니다.
TEAM_ID
채널 헤더에서 세 개의 점(...)을 클릭하고 채널에 대한 링크 가져오기를 선택합니다.
팝업 창에 표시되는 링크에서 채널 ID는 다음 문자와 숫자
channel/
의 문자열입니다. 예를 들어 링크 "https://teams.microsoft.com/l/channel/19%3aQK02.../"에서 채널 ID는 19%3aQK02... 다음/
문자까지채널 ID를 복사하여 .env
CHANNEL_ID
합니다.계속하기 전에 env 파일을 저장합니다.
애플리케이션 및 API 서버 시작/다시 시작
이 시점까지 완료한 연습에 따라 다음 단계 중 하나를 수행합니다.
이전 연습에서 데이터베이스, API 서버 및 웹 서버를 시작한 경우 API 서버 및 웹 서버를 중지하고 다시 시작하여 .env 파일 변경 내용을 선택해야 합니다. 데이터베이스를 실행 상태로 둘 수 있습니다.
API 서버 및 웹 서버를 실행하는 터미널 창을 찾아 Ctrl+C를 눌러 중지합니다. 각 터미널 창에 입력하고
npm start
Enter 키를 눌러 다시 시작합니다. 다음 연습을 계속합니다.데이터베이스, API 서버 및 웹 서버를 아직 시작하지 않은 경우 다음 단계를 완료합니다.
다음 단계에서는 Visual Studio Code에서 세 개의 터미널 창을 만듭니다.
Visual Studio Code 파일 목록에서 .env 파일을 마우스 오른쪽 단추로 클릭하고 통합 터미널에서 열기를 선택합니다. 계속하기 전에 터미널이 프로젝트의 루트인 openai-acs-msgraph 에 있는지 확인합니다.
다음 옵션 중 하나를 선택하여 PostgreSQL 데이터베이스를 시작합니다.
Docker Desktop을 설치하고 실행 중인 경우 터미널 창에서 실행하고
docker-compose up
Enter 키를 누릅니다.Podman-compose가 설치되고 실행 중인 Podman이 있는 경우 터미널 창에서 실행하고
podman-compose up
Enter 키를 누릅니다.Docker Desktop, Podman, nerdctl 또는 설치한 다른 컨테이너 런타임을 사용하여 PostgreSQL 컨테이너를 직접 실행하려면 터미널 창에서 다음 명령을 실행합니다.
Mac, Linux 또는 Linux용 Windows 하위 시스템(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
PowerShell이 있는 Windows:
[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
데이터베이스 컨테이너가 시작되면 Visual Studio Code +의 아이콘을 눌러 두 번째 터미널 창을 만듭니다.
cd
서버/typescript 폴더로 이동하고 다음 명령을 실행하여 종속성을 설치하고 API 서버를 시작합니다.npm install
npm start
+ Visual Studio Code 터미널 도구 모음에서 아이콘을 다시 눌러 세 번째 터미널 창을 만듭니다.
cd
클라이언트 폴더에 다음 명령을 실행하여 종속성을 설치하고 웹 서버를 시작합니다.npm install
npm start
브라우저가 시작되고 이 브라우저로 이동 http://localhost:4200됩니다.
조직 데이터: 사용자 로그인 및 액세스 토큰 가져오기
Microsoft Graph가 조직 데이터에 액세스하려면 사용자가 Microsoft Entra ID를 사용하여 인증해야 합니다. 이 연습에서는 Microsoft Graph 도구 키트의 mgt-login
구성 요소를 사용하여 사용자를 인증하고 액세스 토큰을 검색하는 방법을 알아봅니다. 그런 다음 액세스 토큰을 사용하여 Microsoft Graph를 호출할 수 있습니다.
참고 항목
Microsoft Graph를 접하는 경우 Microsoft Graph 기본 사항 학습 경로에서 자세한 내용을 알아볼 수 있습니다.
이 연습에서 다음을 수행합니다.
- Microsoft Entra ID 앱을 Microsoft Graph 도구 키트와 연결하여 사용자를 인증하고 조직 데이터를 검색하는 방법을 알아봅니다.
- 범위의 중요성에 대해 알아봅니다.
- Microsoft Graph 도구 키트의 mgt-login 구성 요소를 사용하여 사용자를 인증하고 액세스 토큰을 검색하는 방법을 알아봅니다.
로그인 기능 사용
이전 연습에서는 Microsoft Entra ID에서 앱 등록을 만들고 애플리케이션 서버 및 API 서버를 시작했습니다. 또한 파일에서
.env
다음 값을 업데이트했습니다(TEAM_ID
선택CHANNEL_ID
사항).ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE> TEAM_ID=<TEAMS_TEAM_ID> CHANNEL_ID=<TEAMS_CHANNEL_ID>
계속하기 전에 이전 연습을 완료했는지 확인합니다.
브라우저()http://localhost:4200로 돌아가서 헤더에서 로그인을 선택하고 Microsoft 365 개발자 테넌트에서 관리자 사용자 계정을 사용하여 로그인합니다.
팁
Microsoft 365 개발자 테넌트 관리자 계정으로 로그인합니다. Microsoft 365 관리 센터 이동하여 개발자 테넌트에서 다른 사용자를 볼 수 있습니다.
애플리케이션에 처음으로 로그인하는 경우 애플리케이션에서 요청한 권한에 동의하라는 메시지가 표시됩니다. 코드를 탐색할 때 다음 섹션에서 이러한 권한("범위"라고도 함)에 대해 자세히 알아봅니다. 수락을 선택하여 계속합니다.
로그인하면 헤더에 표시되는 사용자의 이름이 표시됩니다.
로그인 코드 탐색
이제 로그인했으므로 사용자를 로그인하고 액세스 토큰 및 사용자 프로필을 검색하는 데 사용되는 코드를 살펴보겠습니다. Microsoft Graph 도구 키트의 일부인 mgt-login 웹 구성 요소에 대해 알아봅니다.
팁
Visual Studio Code를 사용하는 경우 다음을 선택하여 파일을 직접 열 수 있습니다.
- Windows/Linux: Ctrl+P
- Mac: Cmd + P
그런 다음 열려는 파일의 이름을 입력합니다.
클라이언트/package.json 열고
@microsoft/mgt
해당 패키지가@microsoft/mgt-components
종속성에 포함되어 있는지 확인합니다. 이@microsoft/mgt
패키지에는 MSAL(Microsoft 인증 라이브러리) 공급자 기능 및 mgt-login과 같은 웹 구성 요소 및 사용자를 로그인하고 조직 데이터를 검색하고 표시하는 데 사용할 수 있는 기타 구성 요소가 포함되어 있습니다.클라이언트/src/main.ts 열고 패키지에서 다음 가져오기를
@microsoft/mgt-components
확인합니다. 가져온 기호는 애플리케이션에서 사용되는 Microsoft Graph 도구 키트 구성 요소를 등록하는 데 사용됩니다.import { registerMgtLoginComponent, registerMgtSearchResultsComponent, registerMgtPersonComponent, } from '@microsoft/mgt-components';
파일 아래쪽으로 스크롤하여 다음 코드를 확인합니다.
registerMgtLoginComponent(); registerMgtSearchResultsComponent(); registerMgtPersonComponent();
이 코드는
mgt-login
,mgt-search-results
및mgt-person
웹 구성 요소를 등록하고 애플리케이션에서 사용할 수 있도록 합니다.mgt-login 구성 요소를 사용하여 사용자를 로그인하려면 Microsoft Entra ID 앱의 클라이언트 ID(.env
ENTRAID_CLIENT_ID
됨)를 참조하고 사용해야 합니다.graph.service.ts 열고 함수를 찾습니다
init()
. 파일의 전체 경로는 클라이언트/src/app/core/graph.service.ts. 다음과 같은 가져오기 및 코드가 표시됩니다.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'); } }
이 코드는 앱
Msal2Provider
등록에서 Microsoft Entra ID 클라이언트 ID를 전달하고scopes
앱이 액세스를 요청할 새 개체를 만듭니다. 앱이scopes
액세스할 Microsoft Graph 리소스에 대한 액세스를 요청하는 데 사용됩니다. 개체를Msal2Provider
만든 후에는 Microsoft Graph 도구 키트 구성 요소에서 Microsoft Graph에서 데이터를 검색하는 데 사용되는 개체에 할당Providers.globalProvider
됩니다.편집기에서 header.component.html 열고 mgt-login 구성 요소를 찾 습니다. 파일의 전체 경로가 client/src/app/header/header.component.html.
@if (this.featureFlags.microsoft365Enabled) { <mgt-login class="mgt-dark" (loginCompleted)="loginCompleted()"></mgt-login> }
mgt-login 구성 요소는 사용자 로그인을 사용하도록 설정하고 Microsoft Graph와 함께 사용되는 토큰에 대한 액세스를 제공합니다. 로그인에 성공하면 함수를
loginCompleted
호출loginCompleted()
하는 이벤트가 트리거됩니다. mgt-login은 이 예제의 Angular 구성 요소 내에서 사용되지만 모든 웹 애플리케이션과 호환됩니다.mgt-login 구성 요소의 표시는 설정
featureFlags.microsoft365Enabled
되는 값에true
따라 달라집니다. 이 사용자 지정 플래그는 환경 변수가ENTRAID_CLIENT_ID
있는지 확인하여 애플리케이션이 올바르게 구성되고 Microsoft Entra ID에 대해 인증할 수 있는지 확인합니다. 사용자가 전체 연습 시퀀스를 따르지 않고 자습서 내에서 AI 또는 통신 연습만 완료하도록 선택하는 경우를 수용하기 위해 플래그가 추가됩니다.header.component.ts 열고 함수를 찾습니다
loginCompleted
. 이 함수는 이벤트가 내보내지고 로그인한 사용자 프로필loginCompleted
검색을 처리할 때Providers.globalProvider
호출됩니다.async loginCompleted() { const me = await Providers.globalProvider.graph.client.api('me').get(); this.userLoggedIn.emit(me); }
이 예제에서는 Microsoft Graph
me
API를 호출하여 사용자의 프로필을 검색합니다(me
현재 로그인한 사용자를 나타냅니다). 코드 문은this.userLoggedIn.emit(me)
구성 요소에서 이벤트를 내보내 프로필 데이터를 부모 구성 요소에 전달합니다. 이 경우 부모 구성 요소는 애플리케이션의 루트 구성 요소인 app.component.ts 파일입니다.mgt-login 구성 요소에 대한 자세한 내용은 Microsoft Graph 도구 키트 설명서를 참조하세요.
이제 애플리케이션에 로그인했으므로 조직 데이터를 검색하는 방법을 살펴보겠습니다.
조직 데이터: 파일 검색, 채팅 및 Teams에 메시지 보내기
오늘날의 디지털 환경에서 사용자는 전자 메일, 채팅, 파일, 일정 이벤트 등을 비롯한 다양한 조직 데이터를 사용합니다. 이로 인해 작업 또는 애플리케이션 간 전환과 같은 빈번한 컨텍스트 변화가 발생할 수 있으며, 이로 인해 포커스가 중단되고 생산성이 저하됩니다. 예를 들어 프로젝트에서 작업하는 사용자는 전자 메일에서 중요한 세부 정보를 찾거나 관련 파일을 찾기 위해 비즈니스용 OneDrive 전환하기 위해 현재 응용 프로그램에서 Outlook으로 전환해야 할 수 있습니다. 이 전후 작업은 포커스를 방해하고 당면한 작업에 더 잘 소비될 수 있는 시간을 낭비합니다.
효율성을 높이기 위해 조직 데이터를 사용자가 매일 사용하는 애플리케이션에 직접 통합할 수 있습니다. 애플리케이션에 조직 데이터를 가져와서 사용자는 정보에 더 원활하게 액세스하고 관리할 수 있으므로 컨텍스트 이동을 최소화하고 생산성을 향상시킬 수 있습니다. 또한 이 통합은 중요한 인사이트와 컨텍스트를 제공하여 사용자가 정보에 입각한 의사 결정을 내리고 보다 효과적으로 작업할 수 있도록 합니다.
이 연습에서 다음을 수행합니다.
- Microsoft Graph 도구 키트의 mgt-search-results 웹 구성 요소를 사용하여 파일을 검색하는 방법을 알아봅니다.
- Microsoft Graph를 직접 호출하여 microsoft Teams에서 비즈니스용 OneDrive 및 채팅 메시지에서 파일을 검색하는 방법을 알아봅니다.
- Microsoft Graph를 사용하여 Microsoft Teams 채널에 채팅 메시지를 보내는 방법을 이해합니다.
조직 데이터 기능 사용
이전 연습에서는 Microsoft Entra ID에서 앱 등록을 만들고 애플리케이션 서버 및 API 서버를 시작했습니다. 또한 파일에서 다음 값을 업데이트했습니다
.env
.ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE> TEAM_ID=<TEAMS_TEAM_ID> CHANNEL_ID=<TEAMS_CHANNEL_ID>
계속하기 전에 이전 연습을 완료했는지 확인합니다.
브라우저(http://localhost:4200)로 돌아갑니다. 아직 로그인하지 않은 경우 헤더에서 로그인을 선택하고 Microsoft 365 개발자 테넌트의 사용자로 로그인합니다.
참고 항목
사용자를 인증하는 것 외에도 mgt-login 웹 구성 요소는 Microsoft Graph에서 파일, 채팅, 전자 메일, 일정 이벤트 및 기타 조직 데이터에 액세스하는 데 사용할 수 있는 액세스 토큰을 검색합니다. 액세스 토큰에는 이전에 본 범위(권한)
Chat.ReadWrite
Files.Read.All
및 기타 항목이 포함됩니다.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'] });
datagrid에서 Adatum Corporation 행에 대한 관련 콘텐츠 보기를 선택합니다. 이렇게 하면 파일, 채팅, 전자 메일 및 일정 이벤트와 같은 조직 데이터가 Microsoft Graph를 사용하여 검색됩니다. 데이터가 로드되면 탭 인터페이스의 데이터 그리드 아래에 표시됩니다. Microsoft 365 개발자 테넌트의 사용자에 대한 파일, 채팅, 전자 메일 또는 일정 이벤트를 아직 추가하지 않았기 때문에 이 시점에서 데이터가 표시되지 않을 수 있음을 언급하는 것이 중요합니다. 다음 단계에서 이 문제를 해결해 보겠습니다.
Microsoft 365 테넌트에는 이 단계에서 Adatum Corporation에 대한 관련 조직 데이터가 없을 수 있습니다. 일부 샘플 데이터를 추가하려면 다음 작업 중 하나 이상을 수행합니다.
Microsoft 365 개발자 테넌트 자격 증명을 https://onedrive.com 사용하여 방문하여 로그인하여 파일을 추가합니다.
- 왼쪽 탐색 창에서 내 파일을 선택합니다.
- + 새로 추가를 선택한 다음 메뉴에서 폴더 업로드를 선택합니다.
- 복제한 프로젝트에서 openai-acs-msgraph/customer 문서 폴더를 선택합니다.
Microsoft 365 개발자 테넌트 자격 증명을 사용하여 방문하고 로그인하여 https://teams.microsoft.com 채팅 메시지 및 일정 이벤트를 추가합니다.
왼쪽 탐색 창에서 Teams를 선택합니다.
팀 및 채널을 선택합니다.
게시물 시작을 선택합니다.
제목에 대한 Adatum Corporation에 대한 새 주문과 메시지 본문에 추가하려는 추가 텍스트를 입력합니다. 게시 단추를 선택합니다.
Adventure Works Cycles, Contoso Pharmaceuticals 및 Tailwind Traders와 같은 애플리케이션에서 사용되는 다른 회사를 언급하는 추가 채팅 메시지를 자유롭게 추가할 수 있습니다.
왼쪽 탐색 영역에서 일정을 선택합니다.
새 모임을 선택합니다.
제목과 본문에 대해 "프로젝트 일정에 대해 Adatum Corporation과 만남"을 입력합니다.
저장을 선택합니다.
Microsoft 365 개발자 테넌트 자격 증명을 https://outlook.com 사용하여 방문하여 로그인하여 전자 메일을 추가합니다.
새 메일을 선택합니다.
To 필드에 개인 전자 메일 주소를 입력합니다.
주체 및 본문에 대해 원하는 모든 항목에 대해 Adatum Corporation에 대한 새 주문을 입력합니다.
보내기를 선택합니다.
브라우저에서 애플리케이션으로 돌아가서 페이지를 새로 고칩니다. Adatum Corporation 행에 대해 관련 콘텐츠 보기를 다시 선택합니다. 이제 이전 단계에서 수행한 작업에 따라 탭에 데이터가 표시됩니다.
애플리케이션에서 조직 데이터 기능을 사용하도록 설정하는 코드를 살펴보겠습니다. 데이터를 검색하기 위해 애플리케이션의 클라이언트 쪽 부분은 이전에 살펴본 mgt-login 구성 요소에서 검색한 액세스 토큰을 사용하여 Microsoft Graph API를 호출합니다.
파일 검색 코드 탐색
팁
Visual Studio Code를 사용하는 경우 다음을 선택하여 파일을 직접 열 수 있습니다.
- Windows/Linux: Ctrl+P
- Mac: Cmd + P
그런 다음 열려는 파일의 이름을 입력합니다.
먼저 비즈니스용 OneDrive 파일 데이터를 검색하는 방법을 살펴보겠습니다. files.component.html 열고 코드를 살펴보세요. 파일의 전체 경로가 client/src/app/files/files.component.html.
mgt-search-results 구성 요소를 찾고 다음 특성을 확인합니다.
<mgt-search-results class="search-results" entity-types="driveItem" [queryString]="searchText" (dataChange)="dataChange($any($event))" />
mgt-search-results 구성 요소는 Microsoft Graph 도구 키트의 일부이며 이름에서 알 수 있듯이 Microsoft Graph의 검색 결과를 표시하는 데 사용됩니다. 구성 요소는 이 예제에서 다음 기능을 사용합니다.
이
class
특성은 CSS 클래스를 구성 요소에search-results
적용하도록 지정하는 데 사용됩니다.이
entity-types
특성은 검색할 데이터 형식을 지정하는 데 사용됩니다. 이 경우 값은driveItem
비즈니스용 OneDrive 파일을 검색하는 데 사용됩니다.이
queryString
특성은 검색어를 지정하는 데 사용됩니다. 이 경우 값은 사용자가 datagrid의searchText
행에 대한 관련 콘텐츠 보기를 선택할 때 파일 구성 요소에 전달되는 속성에 바인딩됩니다. 주위queryString
의 대괄호는 속성이 값에searchText
바인딩되어 있음을 나타냅니다.검색
dataChange
결과가 변경되면 이벤트가 발생합니다. 이 경우 파일 구성 요소에서 명명된dataChange()
고객 함수가 호출되고 이벤트 데이터가 함수에 전달됩니다. 주변의dataChange
괄호는 이벤트가 함수에dataChange()
바인딩되어 있음을 나타냅니다.사용자 지정 템플릿이 제공되지 않으므로 기본 템플릿이 기본 제공
mgt-search-results
되어 검색 결과를 표시하는 데 사용됩니다.
mgt-search-results와 같은 구성 요소를 사용하는 대신 코드를 사용하여 Microsoft Graph API를 직접 호출하는 것입니다. 작동 방식을 확인하려면 graph.service.ts 파일을 열고
searchFiles()
파일의 전체 경로는 클라이언트/src/app/core/graph.service.ts.매개 변수가 함수에
query
전달되는 것을 알 수 있습니다. 사용자가 datagrid의 행에 대한 관련 콘텐츠 보기를 선택할 때 전달되는 검색 용어입니다. 검색 용어가 전달되지 않으면 빈 배열이 반환됩니다.async searchFiles(query: string) { const files: DriveItem[] = []; if (!query) return files; ... }
그런 다음 수행할 검색 유형을 정의하는 필터가 만들어집니다. 이 경우 코드는 비즈니스용 OneDrive 파일을 검색하므로
driveItem
앞서 구성 요소에서mgt-search-results
보았던 것처럼 사용됩니다. 이는 이전에 본 mgt-search-resultsdriveItem
전달하는entity-types
것과 같습니다. 그런 다음 매개query
변수가 .와queryString
함께 필터에ContentType:Document
추가됩니다.const filter = { "requests": [ { "entityTypes": [ "driveItem" ], "query": { "queryString": `${query} AND ContentType:Document` } } ] };
그런 다음 함수를
/search/query
사용하여 Microsoft Graph API를 호출합니다Providers.globalProvider.graph.client.api()
. 개체는filter
데이터를 API로post()
보내는 함수에 전달됩니다.const searchResults = await Providers.globalProvider.graph.client.api('/search/query').post(filter);
그런 다음 검색 결과를 반복하여 을 찾
hits
습니다. 각hit
문서에는 발견된 문서에 대한 정보가 포함됩니다. 명명된resource
속성은 문서 메타데이터를 포함하고 배열에files
추가됩니다.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); } } } }
files
그런 다음 배열이 호출자에게 반환됩니다.return files;
이 코드를 살펴보면 앞에서 탐색한 mgt-search-results 웹 구성 요소가 많은 작업을 수행하고 작성해야 하는 코드의 양을 크게 줄이는 것을 확인할 수 있습니다. 그러나 Microsoft Graph를 직접 호출하여 API로 전송되는 데이터 또는 결과 처리 방법을 더 자세히 제어하려는 시나리오가 있을 수 있습니다.
files.component.ts 파일을 열고 함수를 찾습니다
search()
. 파일의 전체 경로는 클라이언트/src/app/files/files.component.ts.이 함수의 본문은 mgt-search-results 구성 요소가 사용 중이므로 주석 처리되지만 사용자가 datagrid의 행에 대한 관련 콘텐츠 보기를 선택할 때 이 함수를 사용하여 Microsoft Graph를 호출할 수 있습니다. 함수는
search()
graph.service.tssearchFiles()
하고 매개 변수를 전달합니다query
(이 예제에서는 회사의 이름). 그런 다음 검색 결과가 구성 요소의data
속성에 할당됩니다.override async search(query: string) { this.data = await this.graphService.searchFiles(query); }
그런 다음 파일 구성 요소는 속성을 사용하여
data
검색 결과를 표시할 수 있습니다. 사용자 지정 HTML 바인딩을 사용하거나 명명된mgt-file-list
다른 Microsoft Graph 도구 키트 컨트롤을 사용하여 이 작업을 처리할 수 있습니다. 다음은 사용자가 파일과 상호 작용할 때 속성을 명명된data
구성 요소의 속성 중 하나에 바인딩files
하고itemClick
이벤트를 처리하는 예제입니다.<mgt-file-list (itemClick)="itemClick($any($event))" [files]="data"></mgt-file-list>
이전에 표시된 mgt-search-results 구성 요소를 사용하거나 Microsoft Graph를 호출하는 사용자 지정 코드를 작성할지 여부는 특정 시나리오에 따라 달라집니다. 이 예제 에서는 mgt-search-results 구성 요소를 사용하여 코드를 단순화하고 수행해야 하는 작업의 양을 줄입니다.
Teams 채팅 메시지 검색 코드 탐색
graph.service.ts 돌아가서 함수를 찾습니다
searchChatMessages()
. 앞에서 살펴본 함수와searchFiles()
비슷하다는 것을 알 수 있습니다.- 필터 데이터를 Microsoft Graph의
/search/query
API에 게시하고 결과를 검색어와teamId
일치하는 개체의channelId
messageId
배열로 변환합니다. - Teams 채널 메시지를 검색하기 위해 API 및
/teams/${chat.teamId}/channels/${chat.channelId}/messages/${chat.messageId}
,teamId
channelId
에 대한 두 번째 호출messageId
이 전달됩니다. 그러면 전체 메시지 세부 정보가 반환됩니다. - 추가 필터링 작업이 수행되고 결과 메시지가 호출자에게 반환
searchChatMessages()
됩니다.
- 필터 데이터를 Microsoft Graph의
chats.component.ts 파일을 열고 함수를 찾습니다
search()
. 파일의 전체 경로는 클라이언트/src/app/chats/chats.component.ts. 함수는search()
graph.service.tssearchChatMessages()
하고 매개 변수를query
전달합니다.override async search(query: string) { this.data = await this.graphService.searchChatMessages(query); }
검색 결과는 구성 요소의 속성에
data
할당되고 데이터 바인딩은 결과 배열을 반복하고 데이터를 렌더링하는 데 사용됩니다. 다음은 Angular Material 카드 구성 요소를 사용하여 검색 결과를 표시하는 예제입니다.@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> }
Microsoft Teams 채널에 메시지 보내기
애플리케이션은 Microsoft Teams 채팅 메시지를 검색하는 것 외에도 사용자가 Microsoft Teams 채널에 메시지를 보낼 수 있도록 합니다. 이 작업은 Microsoft Graph의 엔드포인트를
/teams/${teamId}/channels/${channelId}/messages
호출하여 수행할 수 있습니다.다음 코드에서는 값과
teamId
값을 포함하는channelId
URL이 만들어지는 것을 볼 수 있습니다. 환경 변수 값은 이 예제에서 팀 ID 및 채널 ID에 사용되지만 이러한 값은 Microsoft Graph를 사용하여 동적으로 검색될 수 있습니다. 상수에는body
보낼 메시지가 포함됩니다. 그런 다음 POST 요청이 생성되고 결과가 호출자에게 반환됩니다.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' }; }
Microsoft Graph에서 이러한 유형의 기능을 활용하면 사용자가 이미 사용 중인 애플리케이션에서 직접 Microsoft Teams와 상호 작용할 수 있도록 하여 사용자 productivbity를 향상시킬 수 있습니다.
조직 데이터: 전자 메일 및 일정 이벤트 검색
이전 연습에서는 Microsoft Graph 및 Microsoft Graph 도구 키트의 mgt-search-results 구성 요소를 사용하여 Microsoft Teams에서 비즈니스용 OneDrive 및 채팅에서 파일을 검색하는 방법을 알아보았습니다. Microsoft Teams 채널에 메시지를 보내는 방법도 알아보았습니다. 이 연습에서는 Microsoft Graph에서 전자 메일 메시지 및 일정 이벤트를 검색하고 애플리케이션에 통합하는 방법을 알아봅니다.
이 연습에서 다음을 수행합니다.
- Microsoft Graph 도구 키트의 mgt-search-results 웹 구성 요소를 사용하여 전자 메일 및 일정 이벤트를 검색하는 방법을 알아봅니다.
- mgt-search-results 구성 요소를 사용자 지정하여 사용자 지정 방식으로 검색 결과를 렌더링하는 방법을 알아봅니다.
- Microsoft Graph를 직접 호출하여 전자 메일 및 일정 이벤트를 검색하는 방법을 알아봅니다.
전자 메일 메시지 검색 코드 탐색
팁
Visual Studio Code를 사용하는 경우 다음을 선택하여 파일을 직접 열 수 있습니다.
- Windows/Linux: Ctrl+P
- Mac: Cmd + P
그런 다음 열려는 파일의 이름을 입력합니다.
이전 연습에서는 Microsoft Entra ID에서 앱 등록을 만들고 애플리케이션 서버 및 API 서버를 시작했습니다. 또한 파일에서 다음 값을 업데이트했습니다
.env
.ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE> TEAM_ID=<TEAMS_TEAM_ID> CHANNEL_ID=<TEAMS_CHANNEL_ID>
계속하기 전에 이전 연습을 완료했는지 확인합니다.
emails.component.html 열고 잠시 코드를 살펴보세요. 파일의 전체 경로가 client/src/app/emails/emails.component.html.
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>
mgt-search-results 구성 요소의 이 예제는 이전에 살펴본 것과 동일한 방식으로 구성됩니다. 유일한 차이점은
entity-types
특성이 전자 메일 메시지를 검색하는message
데 사용되고 빈 템플릿이 제공된다는 것입니다.- 이
class
특성은 CSS 클래스를 구성 요소에search-results
적용하도록 지정하는 데 사용됩니다. - 이
entity-types
특성은 검색할 데이터 형식을 지정하는 데 사용됩니다. 이 경우 값은message
가 됩니다. - 이
queryString
특성은 검색어를 지정하는 데 사용됩니다. - 검색
dataChange
결과가 변경되면 이벤트가 발생합니다. 이메일 구성 요소의dataChange()
함수가 호출되고, 결과가 전달되고, 명명data
된 속성이 구성 요소에서 업데이트됩니다. - 구성 요소에 대해 빈 템플릿이 정의됩니다. 이 유형의 템플릿은 일반적으로 검색 결과가 렌더링되는 방법을 정의하는 데 사용됩니다. 그러나 이 시나리오에서는 구성 요소에 메시지 데이터를 렌더링하지 말라고 말하고 있습니다. 대신 표준 데이터 바인딩을 사용하여 데이터를 직접 렌더링합니다(이 경우 Angular가 사용되지만 원하는 라이브러리/프레임워크를 사용할 수 있습니다).
- 이
emails.component.html mgt-search-results 구성 요소 아래에서 전자 메일 메시지를 렌더링하는 데 사용되는 데이터 바인딩을 찾습니다. 이 예제에서는 속성을 반복
data
하고 전자 메일 제목, 본문 미리 보기 및 전체 전자 메일 메시지를 볼 수 있는 링크를 작성합니다.@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> }
microsoft Graph는 mgt-search-results 구성 요소를 사용하여 메시지를 검색하는 것 외에도 전자 메일을 검색하는 데 사용할 수 있는 여러 API를 제공합니다. 앞에서 본 API는
/search/query
확실히 사용될 수 있지만 더 간단한 옵션은 API입니다messages
.이 API를 호출하는 방법을 보려면 graph.service.ts 돌아가서 함수를 찾습니다
searchEmailMessages()
. Microsoft Graph의 엔드포인트를 호출messages
하는 데 사용할 수 있는 URL을 만들고 매개 변수에query
값을$search
할당합니다. 그런 다음 코드는 GET 요청을 수행하고 결과를 호출자에게 반환합니다. 연산자는$search
제목, 본문 및 보낸 사람 필드의 값을 자동으로 검색query
합니다.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; }
searchEmailMessages()
구성 요소는 결과를 UI에 표시합니다.override async search(query: string) { this.data = await this.graphService.searchEmailMessages(query); }
일정 이벤트 검색 코드 탐색
mgt-search-results 구성 요소를 사용하여 일정 이벤트 검색을 수행할 수도 있습니다. 결과 렌더링을 처리할 수 있지만 이 연습의 뒷부분에서 볼 수 있는 고유한 템플릿을 정의할 수도 있습니다.
calendar-events.component.html 열고 코드를 살펴보세요. 파일의 전체 경로가 client/src/app/calendar-events/calendar-events.component.html. 이전에 살펴본 파일 및 전자 메일 구성 요소와 매우 유사합니다.
<mgt-search-results class="search-results" entity-types="event" [queryString]="searchText" (dataChange)="dataChange($any($event))"> <template data-type="result-event"></template> </mgt-search-results>
mgt-search-results 구성 요소의 이 예제는 이전에 살펴본 것과 동일한 방식으로 구성됩니다. 유일한 차이점은
entity-types
달력 이벤트를 검색하는event
데 사용되는 특성이 설정되고 빈 템플릿이 제공된다는 것입니다.- 이
class
특성은 CSS 클래스를 구성 요소에search-results
적용하도록 지정하는 데 사용됩니다. - 이
entity-types
특성은 검색할 데이터 형식을 지정하는 데 사용됩니다. 이 경우 값은event
가 됩니다. - 이
queryString
특성은 검색어를 지정하는 데 사용됩니다. - 검색
dataChange
결과가 변경되면 이벤트가 발생합니다. 일정 이벤트 구성 요소의dataChange()
함수가 호출되고 결과가 전달되고 구성 요소에서 명명data
된 속성이 업데이트됩니다. - 구성 요소에 대해 빈 템플릿이 정의됩니다. 이 시나리오에서는 구성 요소에 데이터를 렌더링하지 말라고 합니다. 대신 표준 데이터 바인딩을 사용하여 데이터를 직접 렌더링합니다.
- 이
calendar-events.component.html
mgt-search-results
바로 아래에서 일정 이벤트를 렌더링하는 데 사용되는 데이터 바인딩을 찾을 수 있습니다. 이 예제에서는 속성을 반복data
하고 이벤트의 시작 날짜, 시간 및 제목을 기록합니다. 구성 요소에 포함된 사용자 지정 함수(예:dayFromDateTime()
timeRangeFromEvent()
데이터 형식을 올바르게 지정하기 위해 호출됨). HTML 바인딩에는 Outlook에서 일정 이벤트를 볼 수 있는 링크와 지정된 경우 이벤트의 위치도 포함됩니다.@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> }
Microsoft Graph는 API를 사용하여
search/query
일정 이벤트를 검색하는 것 외에도 일정 이벤트를 검색하는 데 사용할 수 있는 API를 제공합니다events
. graph.service.ts 함수를searchCalendarEvents()
찾습니다.함수는
searchCalendarEvents()
검색할 기간을 정의하는 데 사용되는 시작 및 종료 날짜/시간 값을 만듭니다. 그런 다음 Microsoft Graph의 엔드포인트를 호출events
하는 데 사용할 수 있는 URL을 만들고 매개 변수와 시작 및 종료 날짜/시간 변수를 포함합니다query
. 그런 다음 GET 요청이 생성되고 결과가 호출자에게 반환됩니다.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; }
생성된 URL의 분석은 다음과 같습니다.
-
/me/events
URL 부분은 로그인한 사용자의 이벤트를 검색하도록 지정하는 데 사용됩니다. -
startdatetime
및enddatetime
매개 변수는 검색 기간을 정의하는 데 사용됩니다. 이 경우 검색은 다음 7일 이내에 시작되는 이벤트를 반환합니다. -
$filter
쿼리 매개 변수는 값을 사용하여 결과를query
필터링하는 데 사용됩니다(이 경우 datagrid에서 선택한 회사 이름). 이contains()
함수는 달력 이벤트의 속성에서query
값을 찾는subject
데 사용됩니다. -
$orderby
쿼리 매개 변수는 속성별로start/dateTime
결과를 정렬하는 데 사용됩니다.
-
url
생성되면 값을url
사용하여 Microsoft Graph API에 GET 요청이 생성되고 결과가 호출자에게 반환됩니다.이전 구성 요소 와 마찬가지로 달력 이벤트 구성 요소(calendar-events.component.ts 파일)는 결과를 호출
search()
하고 표시합니다.override async search(query: string) { this.data = await this.graphService.searchCalendarEvents(query); }
참고 항목
사용자 지정 API 또는 서버 쪽 애플리케이션에서도 Microsoft Graph를 호출할 수 있습니다. Azure Function에서 Microsoft Graph API를 호출하는 예제를 보려면 다음 자습서를 참조하세요.
이제 Microsoft Graph를 사용하여 파일, 채팅, 전자 메일 메시지 및 일정 이벤트를 검색하는 예제를 살펴보았습니다. 다른 Microsoft Graph API에도 동일한 개념을 적용할 수 있습니다. 예를 들어 Microsoft Graph 사용자 API를 사용하여 조직의 사용자를 검색할 수 있습니다. Microsoft Graph 그룹 API를 사용하여 조직에서 그룹을 검색할 수도 있습니다. 설명서에서 Microsoft Graph API의 전체 목록을 볼 수 있습니다.
축하합니다!
이 자습서를 완료했습니다.
축하합니다! 이 자습서에서는 다음 방법을 알아보았습니다.
- Azure OpenAI를 사용하여 사용자 생산성을 향상시킬 수 있습니다.
- Azure Communication Services를 사용하여 통신 기능을 통합할 수 있습니다.
- Microsoft Graph API 및 구성 요소를 사용하여 조직 데이터를 검색하고 표시할 수 있습니다.
이러한 기술을 사용하면 컨텍스트 이동을 최소화하고 필요한 의사 결정 정보를 제공하여 사용자 생산성을 높이는 효과적인 솔루션을 만들 수 있습니다.
Azure 리소스 정리
계정에 더 많은 요금이 부과되지 않도록 Azure 리소스를 정리합니다. Azure Portal로 이동하여 다음 리소스를 삭제합니다.
- Azure AI 검색 리소스
- Azure Storage 리소스
- Azure OpenAI 리소스(먼저 모델을 삭제한 다음 Azure OpenAI 리소스를 삭제해야 합니다.)
- Azure Communication Services 리소스
다음 단계
설명서
- Azure OpenAI 문서
- 데이터의 Azure OpenAI
- Azure Communication Services 설명서
- Microsoft Graph 설명서
- Microsoft Graph 도구 키트 설명서
- Microsoft Teams 개발자 설명서
교육 콘텐츠
- Azure OpenAI Service를 사용하여 프롬프트 엔지니어링 적용
- Azure OpenAI Service 시작
- Azure Communication Services 소개
- Microsoft Graph 기본 사항
- 비디오 과정: 초보자를 위한 Microsoft Graph 기본 사항
- JavaScript 개발을 위한 Microsoft Graph 시나리오 살펴보기
- ASP.NET Core 개발을 위한 Microsoft Graph 시나리오 살펴보기
- Microsoft Graph 도구 키트 시작
- Visual Studio Code용 Teams 도구 키트를 사용하여 Microsoft Teams용 앱 빌드 및 배포
본 섹션과 관련하여 문제가 있으십니까? 문제가 있으시면 본 섹션을 개선하기 위해 피드백을 제출해 주세요.