日常業務用にChatGPT(Azure OpenAI Service)とMicrosoft Teamsを連携する。

# はじめに

最近は猫も杓子もChatGPTですね。
本文も、御多分に漏れずChatGPTです。ただし、機密情報を扱えるようにAzure OpenAI Serviceを利用します。
また、最近は日常業務にMicrosoft Teamsをご利用の方も多いと存じます。
本文では、日常業務で手軽にChatGPTをご利用可能なように、TeamsでメンションをするとChatGPTが受け答えをしてくれる仕組みを作ります。

仕組みは簡単。TeamsにメンションをつけるとWebhookしてくれるOutgoing Webhookという仕組みがあるので、Webhoook先にAzure Functionsを用意しておきます。FunctionsからAzure OpenAIをHttp Request経由で呼び出します。言語にはNode.jsを使います。最近のNode.jsでは標準でfetchを使えるから便利。
図にすると以下のような感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25176/094b83c4-de03-c0a8-f305-6df7243cc4fe.png)



早速作っていきます。
本文では、~~文書作成の省力化~~できるだけ最新の情報を参照する　ために、主となる情報の記述に集中し、補足情報は外部リンクでご説明します。文書作成先の企業様、有志様に感謝。

# Azure OpenAI Serviceを作成します。
[Azure OpenAI のリソースを作成します。](https://cptechweb.teldevice.co.jp/hc/ja/articles/17904836139033-Azure-OpenAI-%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E4%BD%9C%E6%88%90%E6%96%B9%E6%B3%95%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84-)

省力化のために、[ネットワークはどこからでもアクセス可能なように設定します](https://learn.microsoft.com/ja-jp/azure/ai-services/cognitive-services-virtual-networks?tabs=portal#supported-regions-and-service-offerings)。
Azure OpenAIに外からアクセスされることを懸念される方は、Azure OpenAIのリソース名に推測困難な長い文字列を入れる（リソース名がURLに含まれるので、アクセスが難しくなる）か、慎重を期したい場合は、ネットワークを適切に設定してください。（[参考]((https://www.softbank.jp/biz/blog/cloud-technology/articles/202306/azure-openai-private-network/)))

# エンドポイントURLとキーを取得します。
作成したOpen AIリソースの「概要」から「探索」を押して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25176/c2b5712a-8b3a-0915-2426-e5ee639c776a.png)


「チャット」を押して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25176/0e3396e3-1d83-5615-f4a4-5749d894ea0a.png)

「チャットセッション」の「コード」のを押して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25176/75aee0ba-812d-e6d3-e09d-3baa8f9108dc.png)

サンプルコードの下に表示されるエンドポイントとキーをコピーしておいてください。

# Functionsを作成
[Functionsを作成](https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-create-function-app-portal)します。HTTPトリガで関数を作成してください。
こちらも、外部からアクセスされたくない場合は推測困難なリソース名、関数名にしてください。慎重を期する場合は、Teamsから鍵を取得可能（事項参照）なので、関数内でその鍵をチェックするようにしてください。

コードは以下です。

```javascript
module.exports = async function (context, req) {
    var receivedMsg = req.body;
    var openAIRequestBody = {
      "messages": [
        {
          "role": "system",
          "content": ""
        },
        {
          "role": "user",
          "content": receivedMsg.text
        },
        {
          "role": "assistant",
          "content": ""
        }
      ],
      "temperature": 0.7,
      "top_p": 0.95,
      "frequency_penalty": 0,
      "presence_penalty": 0,
      "max_tokens": 800,
      "stop": null
    }
    var data = await fetch("Azure　OpenAIのエンドポイント", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
            ,"api-key": "Azure OpenAIのキー"
        },
        body: JSON.stringify(openAIRequestBody), 
    });
    responseContent = (await data.json()).choices[0].message.content;
    
    var responseMsg = JSON.stringify({
        "type": "message",
        "text": responseContent
    });
    context.res = {
        body: responseMsg
    };
}
```

関数を作成したら、上記[Functionsの作成](https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-create-function-app-portal)ページの[関数の URL の取得]の要領でURLをを取得しておいてください。

# TeamsのOutgoing Webhookを作成します。
[Outgoing Webhookを作成](https://learn.microsoft.com/ja-jp/microsoftteams/platform/webhooks-and-connectors/how-to/add-outgoing-webhook?tabs=urljsonpayload%2Cdotnet)します
名前はメンションしやすいものが良いでしょう。Callback URLにはAzure FunctionsのURLを指定してください。
セキュリティーに万全を期する場合は、上記[Outgoing Webhookを作成](https://learn.microsoft.com/ja-jp/microsoftteams/platform/webhooks-and-connectors/how-to/add-outgoing-webhook?tabs=urljsonpayload%2Cdotnet)のページのハッシュ ベースのメッセージ認証コード (HMAC)で作成される認証コードをFunctions内で検証するようにすると良いでしょう。気になるなら。


# Teamsでメンションする。
これで作成したOutgoing Webhookでメンションすると、ChatGPTが返答してくれるようになります！良かったですね。

# 注
本文中にでてくる商品名、サービス名、会社名またはロゴマークは、各社の商標、登録商標もしくは商号のことがあります。