ExcelからOffice Scripts経由で、Outlookの連絡先を追加する（with Graph API）

# 何が何でもExcelで！
そういった熱い思いは度々お聞きします。
気持ちは良くわかります。

しかし`Power Automate lover`としては、何とかして`Power Automate`と絡めたい・・・
そういった気持ちもございます。

それなら・・・
`Office Scripts`いってみるか！ということで書いてみることにしました。

# Outlookの連絡先をExcelからまとめて登録したい
`Outlook`には、連絡先がありますね。
こちらに様々な連絡先を登録することができます。

ただし一件一件まとめて入力するのは手間・・・。
そういったシーンもあるのでは・・・🧐

そういった時には、`Outlook`の[連絡先をインポート](https://support.microsoft.com/ja-jp/office/%E9%80%A3%E7%B5%A1%E5%85%88%E3%82%92-outlook-com-%E3%81%BE%E3%81%9F%E3%81%AFoutlook-on-the-web%E3%81%AB%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B-285a3b55-8d93-4ac8-93df-43fffd13b2f1?ui=en-us&rs=en-us&ad=us)を使用すれば、`CSV`で一括登録が可能です。

https://support.microsoft.com/ja-jp/office/%E9%80%A3%E7%B5%A1%E5%85%88%E3%82%92-outlook-com-%E3%81%BE%E3%81%9F%E3%81%AFoutlook-on-the-web%E3%81%AB%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B-285a3b55-8d93-4ac8-93df-43fffd13b2f1?ui=en-us&rs=en-us&ad=us

![スクリーンショット 2024-06-13 205821.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/8a730b72-5482-5da1-ab76-bfb858413135.png)

一度登録があるものは、再登録もされないので非常に便利です。

無理にExcelでやる必要はありません。
しかし`それでもExcelでやりたいんだ🔥`という熱い思いもあるでしょう。

**車輪の再発明**な感じが否めませんが、`Office Scripts`を書いてみましょう！

## Office Scriptsの利点
`Office Scripts`の利点として、**ブックからPower Automateを起動できること**が挙げられます。


`ブック内にフロー`を追加すれば、ボタンクリック感覚で使えます。
`Power Automate`につなぐことができれば、多様な`API`に繋げることができるので、**可能性は無限大∞**！

またスクリプトである`osts`ファイルを、`SharePoint`に配置することで、複数の人とスクリプトを共有できます。よくわからない削除事故もリカバリーできるので嬉しい限りです。

拡張子にも依存されないので嬉しいですね！

Office Scriptsの用途としては
1. データの集計
1. レポート作成
1. 大きなデータセットの計算処理
1. Power Automateでやりづらいデータ加工

といった様々なところで、活躍します。

さて、肝心な`Outlook`の`連絡先の追加`に移っていきましょう。

## Power Automateの機能
`Power Automate`に標準で、[Outlook 365 連絡先の作成 (V2)](https://learn.microsoft.com/ja-jp/connectors/office365/#%E9%80%A3%E7%B5%A1%E5%85%88%E3%81%AE%E4%BD%9C%E6%88%90-(v2))アクションが存在します。

https://learn.microsoft.com/ja-jp/connectors/office365/#%E9%80%A3%E7%B5%A1%E5%85%88%E3%81%AE%E4%BD%9C%E6%88%90-(v2)

こちらを使えばサクっと`連絡先の追加`はできそうです。
まあサクっといけちゃうわけですよ。

~~つまらない。~~
これをそのままやっても芸がないので、[Microsoft Entra ID 付きの HTTP (事前承認済み)](https://learn.microsoft.com/ja-jp/connectors/webcontents/)を使って、一括登録に試みます。

https://learn.microsoft.com/ja-jp/connectors/webcontents/

## Graph APIを用いた連絡先の登録
`標準コネクタ`の範囲内でできれば嬉しいのですが、第 1 セグメント`/me`、第 2 セグメント`/contacts`なので、妥当なコネクタが思いつきません。

今回紹介している[Microsoft Entra ID 付きの HTTP (事前承認済み)](https://learn.microsoft.com/ja-jp/connectors/webcontents/)は、プレミアムコネクタです。ライセンスにご注意ください。

実際に設定してみると、このようになります。

![スクリーンショット 2024-06-13 211111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/e53cd7bf-fcf9-8858-aff9-99862c208dfe.png)

| キー | 値 |
|:-:|---|
| URI|https://graph.microsoft.com/v1.0/me/contacts |
| Method | POST |

■ ヘッダー

| キー | 値 |
|---|---|
| Content-Type | application/json |

```json:HTTP送信、本文
{
  "givenName": "なまえ",
  "emailAddresses": [
    {
      "address": "メールアドレス",
      "name": "メールアドレスに付帯する名前"
    }
  ],
  "businessPhones": [
    "電話番号"
  ],
  "homeAddress": {
    "street": "住所"
  }
}
```

こちらを使えば、サクっと**連絡先を追加**できます。

ただし一件一件繰り返しするのは、あまりカッコよくないですね。
ということで、まとめてやってみましょう！

## バッチリクエスト
`バッチリクエスト`を使用することで、**複数の連絡先を一度に追加することができるようです**。

![スクリーンショット 2024-06-13 214222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/82e06be8-ac15-12ca-65b2-cfc576d3702c.png)

```plaintext:URI
https://graph.microsoft.com/v1.0/$batch
```

上記に対して、`リクエスト`をまとめて格納します。

```json:二件のコンタクトの追加の場合
{
    "requests": [
        {
            "id": "0",
            "method": "POST",
            "url": "/me/contacts",
            "body": {
                "givenName": "John Doe",
                "emailAddresses": [
                    {
                        "address": "john.doe@example.com",
                        "name": "John Doe"
                    }
                ],
                "businessPhones": [
                    "+1234567890"
                ],
                "homeAddress": {
                    "street": "123 Main St, Springfield, IL"
                }
            },
            "headers": {
                "Content-Type": "application/json"
            }
        },
        {
            "id": "1",
            "method": "POST",
            "url": "/me/contacts",
            "body": {
                "givenName": "Jane Smith",
                "emailAddresses": [
                    {
                        "address": "jane.smith@example.com",
                        "name": "Jane Smith"
                    }
                ],
                "businessPhones": [
                    "+0987654321"
                ],
                "homeAddress": {
                    "street": "456 Elm St, Springfield, IL"
                }
            },
            "headers": {
                "Content-Type": "application/json"
            }
        }
    ]
}
```

ほとんど前述のものと一緒ですね。
**つまり、このJSONを作って送ればOK！**

# Office ScriptsでJSONを作成する
まず先に`A1`セルから下記のような表を格納することを想定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/74e1614f-b2a5-5fb9-df7a-12ee6489c416.png)

| Name | Email | Phone | Address |
|---|---|---|---|
| サカナ 太郎 | sakana.taro@example.com | 090-1234-5678 | 東京都港区魚町1-2-3 |
| エビ 花子 | ebi.hanako@example.com | 090-2345-6789 | 神奈川県横浜市エビ町4-5-6 |
| タコ 次郎 | tako.jiro@example.com | 090-3456-7890 | 大阪府大阪市タコ町7-8-9 |
| カニ 三郎 | kani.saburo@example.com | 090-4567-8901 | 北海道札幌市カニ町10-11-12 |
| イカ しおん | ika.shion@example.com | 090-5678-9012 | 福岡県福岡市イカ町13-14-15 |
| ホタテ 恵子 | hotate.keiko@example.com | 090-6789-0123 | 千葉県千葉市ホタテ町16-17-18 |
| サーモン 竜也 | salmon.tatsuya@example.com | 090-7890-1234 | 新潟県新潟市サーモン町19-20-21 |
| クジラ 雅 | kujira.miyabi@example.com | 090-8901-2345 | 京都府京都市クジラ町22-23-24 |
| ウナギ 守 | unagi.mamoru@example.com | 090-9012-3456 | 愛知県名古屋市ウナギ町25-26-27 |
| サバ 幸子 | saba.sachiko@example.com | 090-0123-4567 | 広島県広島市サバ町28-29-30 |

これを`Office Scripts`で`JSON`にします。

```typescript:ostsファイル
function main(workbook: ExcelScript.Workbook): string {
    // 1. シート名を指定
    const sheetName: string = "data";
    let sheet: ExcelScript.Worksheet = workbook.getWorksheet(sheetName);

    // 2. データ範囲を設定
    const startRow: number = 1;
    const startCol: number = 1;
    const endRow: number = sheet.getUsedRange().getRowCount();
    const endCol: number = 4; // A～D列
    let range = sheet.getRangeByIndexes(startRow - 1, startCol - 1, endRow, endCol);
    let values: string[][] = range.getValues() as string[][];

    // JSONの作成
    let requests: { id: string; method: string; url: string; body; headers: { "Content-Type": string } }[] = [];
    // 1行目はヘッダー
    for (let i: number = 1; i < values.length; i++) {
        let row: string[] = values[i];
        let contactData: {
            givenName: string;
            emailAddresses: { address: string; name: string }[];
            businessPhones: string[];
            homeAddress: { street: string }
        } = {
            givenName: row[0],
            emailAddresses: [
                {
                    address: row[1],
                    name: row[0]
                }
            ],
            businessPhones: [
                row[2]
            ],
            homeAddress: {
                street: row[3]
            }
        };
        requests.push({
            id: i.toString(),
            method: "POST",
            url: "/me/contacts",
            body: contactData,
            headers: {
                "Content-Type": "application/json"
            }
        });
    }

    let batchRequestData: { requests: typeof requests } = {
        requests: requests
    };

    let jsonString: string = JSON.stringify(batchRequestData, null, 2);

    // JSON文字列を戻り値として返す
    return jsonString;
}
```

`A1`から行数を数えて`JSON`にしています。
書き終えたら、`スクリプトの詳細`から`コピーを保存`を選択すると、`SharePoint`にスクリプトが保存されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/ea014a04-220a-d649-388c-4b5c25b8685f.png)

# Power Automate
Power Automateは
1. フローを手動でトリガーする
1. SharePoint ライブラリからスクリプトを実行する
1. [Microsoft Entra ID 付きの HTTP (事前承認済み)](https://learn.microsoft.com/ja-jp/connectors/webcontents/)

の**3ステップ**


# ExcelでPower Automateを呼び出す
[ExcelでPower Automateを呼び出す](https://learn.microsoft.com/ja-jp/power-automate/flows-excel)方法は若干曲者です。

https://learn.microsoft.com/ja-jp/power-automate/flows-excel

`作業の自動化`からテンプレートを選択し、テンプレートを修正する形で対処します。
コチラの操作を実施すると、`Power Automate`フローの編集ができます。

:::note info
テンプレートは選択のたびに、新しくテンプレートに準じたフローを作成する、といった考え方なので、元のテンプレートをいじっているわけではありません。
:::

コチラに先ほどのフローを移植し、環境を整えます。
**これで準備完了です！**


# 実験！
[ 自動化 ]タブの[ 作業の自動化 ]で、Power Automateのアイコンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/cd0959a9-f412-e779-19b4-862380e80f0e.png)

[ このブック内のフロー ]から、Power Automateが起動できます。

![スクリーンショット 2024-06-13 215818.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/b57130d2-6f81-6524-ae7f-3f61310b1db6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/81b75b75-860a-eef9-6d22-bbec18f5b709.png)


そうすると・・・

- Power Automate
![スクリーンショット 2024-06-13 215905.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/e095c943-bc63-e96a-ab7f-c58d2672d227.png)

- Outlook
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/d6e19c62-8649-6e24-7aa4-d57370cc13d9.png)

`Outlook`に反映されました🙌
**めちゃめちゃ車輪の再発明ですね！**

しかし**いろいろなAPIを気軽に使えることは魅力的✨**
**Power Automate Love**です！

# おわりに
`Excelから○○`は、無限∞にネタがわいてきますね・・・。
マラソン🏃期間中、出現率が高そうですが、ご容赦ください🙇