Microsoft Graph

[Google Apps Script]Office 365 unified APIを使ってメールを送信する。

久しぶりのGoogle Apps Scriptネタです。
今回はGoogle Apps ScriptからOffice 365 unified APIを使って、メールを送信してみようと思います。

下準備

  1. [Google Apps Script]OAuth認証(2.0)が必要なWeb APIを利用する。」を参考に、Webアプリケーションとしてスクリプトを作成し、リダイレクト先のURLを取得します。
  2. Office 365 unified APIをVBAから呼び出す」を参考に、クライアント IDを取得します(アプリケーションの種類:ネイティブ クライアント アプリケーション、他のアプリケーションに対するアクセス許可:Office 365 unified API (preview)、デリゲートされたアクセス許可:Send mail as a user)。

コード

・コード.gs

var access_token;
var client_id = '(下準備で取得したクライアント ID)';
var redirect_uri = 'https://script.google.com/macros/s/abcdefg/usercallback'; //下準備で取得したリダイレクト先のURL
var resource_uri = 'https://graph.microsoft.com/';
var token_uri = 'https://login.microsoftonline.com/common/oauth2/token';
var rest_uri = 'https://graph.microsoft.com/beta/me/sendmail';

function doGet(e) {
  var auth_uri = 'https://login.windows.net/common/oauth2/authorize?response_type=code';
  auth_uri += '&redirect_uri=' + encodeURIComponent(redirect_uri);
  auth_uri += '&client_id=' + client_id;
  auth_uri += '&resource=' + encodeURIComponent(resource_uri);
  auth_uri += '&state=' + ScriptApp.newStateToken().withMethod('callback').withTimeout(200).createToken();
  
  var html = '<p style="padding:10px;">';
  html += '<h4>■ Office 365 unified API メール送信サンプル</h4>';
  html += '<a href="' + auth_uri + '">メール送信</a>';
  html += '</p>';
  return HtmlService.createHtmlOutput(html);
}

function callback(e){
  var opt = {
    'method' : 'POST',
    'payload' : {
        'code' : e.parameter.code,
        'client_id' : client_id,
        'redirect_uri' :redirect_uri,
        'grant_type' : 'authorization_code'
    },
    'muteHttpExceptions' : true
  };
  var res = UrlFetchApp.fetch(token_uri, opt);
  var dat = JSON.parse(res.getContentText());
  access_token = dat.access_token;
  return HtmlService.createTemplateFromFile('contents')
                    .evaluate()
                    .setTitle('メール送信サンプル')
                    .setSandboxMode(HtmlService.SandboxMode.NATIVE);
}

function sendMail(address, subject, body, access_token){
//メール送信
// *日本語非対応
// *下記のようにコード変換しても効果なし
// Utilities.newBlob('').setDataFromString(subject, 'UTF-8').getDataAsString('Shift_JIS')
  var json = {
    'Message': {
      'Subject': subject,
      'Body': {
        'ContentType': 'Text',
        'Content': body
      },
      'ToRecipients': [
        {
          'EmailAddress': {
            'Address': address
          }
        }
      ]
    },
    'SaveToSentItems': 'false'
  };
  
  var opt = {
    'method' : 'POST',
    'contentType' : 'application/json',
    'headers' : {
      'Authorization': 'Bearer ' + access_token
    }, 
    'payload': JSON.stringify(json), 
    'muteHttpExceptions' : true
  };
  UrlFetchApp.fetch(rest_uri, opt);
}

・contents.html

<style>
* {
  padding: 10px;
}
td {
  border-style: none;
}
</style>
<table>
  <tr>
    <td>宛先:</td>
    <td><input id="txtAddress" type="text" size="30" value=""></td>
  </tr>
  <tr>
    <td>件名:</td>
    <td><input id="txtSubject" type="text" size="30" value="Test Mail"></td>
  </tr>
  <tr>
    <td>本文</td>
    <td><textarea id="txtBody" cols=40 rows=4>Send Test E-mail</textarea></td>
  </tr>
  <tr>
    <td colspan="2"><input id="btnSend" type="button" value="送信" onclick="btnSend_onClick()"></td>
  </tr>
  <tr><td colspan="2">&nbsp;</td></tr>
  <tr>
    <td colspan="2"><div id="divResults"></div></td>
  </tr>
</table>
<input type="hidden" id="txtAccessToken" value="<?= access_token ?>">
<script>  
  function btnSend_onClick(){
    var objAddress = document.getElementById('txtAddress');
    var objSubject = document.getElementById('txtSubject');
    var objBody = document.getElementById('txtBody');
    var objAccessToken = document.getElementById('txtAccessToken');
    var objResults = document.getElementById('divResults');
    this.disabled = 'true';
    objResults.innerHTML = '';
    google.script.run.withSuccessHandler(onComplete)
                     .withFailureHandler(onComplete)
                     .sendMail(objAddress.value, 
                               objSubject.value, 
                               objBody.value, 
                               objAccessToken.value);
  }
  
  function onComplete(dat){
    var objResults = document.createElement('span');
    var objSend = document.getElementById('btnSend');
    objResults.innerHTML = 'メールを送信しました。';
    document.getElementById('divResults').appendChild(objResults);
    objSend.disabled = '';
  }
</script>

アプリケーションの実行

上記コードをエディタに貼り付けたら、いよいよアプリケーションの実行です。

  1. まずはリクエストを承認するため、doGet関数を実行します。
  2. GAS_Office365unifiedAPI_01

  3. 「承認が必要です」ダイアログが表示されたら「続行」ボタンをクリックします。
  4. GAS_Office365unifiedAPI_02

  5. 「(プロジェクト)が次の許可をリクエストしています」ダイアログが表示されたら「承認する」ボタンをクリックします。
  6. GAS_Office365unifiedAPI_03

  7. 承認が終わったら「公開」メニューから「ウェブ アプリケーションとして導入」をクリックします。
  8. GAS_Office365unifiedAPI_04

  9. 「ウェブ アプリケーションとして導入」ダイアログが表示されたら「最新のコード」リンクをクリックします。
  10. GAS_Office365unifiedAPI_05

  11. 作成したアプリケーション画面が表示されるので「メール送信」リンクをクリックします。
  12. GAS_Office365unifiedAPI_06

  13. 365 APIの認証画面が表示されるので、メールアドレスとパスワードを入力し、「サインイン」ボタンをクリックします。
  14. GAS_Office365unifiedAPI_07

  15. 再びアプリケーション画面が表示されるので、宛先、件名、本文を入力し、「送信」ボタンをクリックします。ちなみに、Google Apps Scriptの仕様かどうかは分からないのですが、件名や本文に日本語を使用すると文字化けが発生します。
  16. GAS_Office365unifiedAPI_08

    GAS_Office365unifiedAPI_09

  17. メール送信先で受信確認すると、アプリケーションから送信したメールが届いていることが確認できます。
  18. GAS_Office365unifiedAPI_10

以上で、Google Apps Scriptで作成したアプリケーションから、Office 365 unified APIを使ってメール送信できることが確認できました。

コードのテスト中、JSON形式で渡す件名や本文の文字コードを変えてみたり、POSTする際のヘッダーを変えてみたりしたのですが、色々やっても送られるメールのcharsetが“us-ascii”になってしまい、日本語を送ることができませんでした。

正直スッキリしないのですが、一応APIの動作は確認できたので、コレで良しとします。

関連記事

  1. Google関連

    [Google Apps Script]Google アナリティクスのデータを取得する。

    拡張サービスの「Google Analytics API」を使って、G…

  2. アイコン一覧

    Office 365アイコン(imageMso)一覧(A)

    Office 365のデスクトップ版Officeアプリケーション(Wo…

  3. Office関連

    Office 365 unified APIをVBAから呼び出す

    前回の記事で、VBAからOffice 365 APIを呼び出す手順につ…

  4. Office関連

    ExcelとPowerPointに自動保存機能が追加されました。

    Excel 2016を使っていて、ふと気が付いたのが画面左上にある「自…

コメント

  • コメント (0)

  • トラックバックは利用できません。

  1. この記事へのコメントはありません。

Time limit is exhausted. Please reload CAPTCHA.

最近の記事

アーカイブ

RapidSSL_SEAL-90x50
PAGE TOP