0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google GAS でスプレッドシートを Excel に変換して Webex Teams でつぶやく multipart/form-data のサンプル

Posted at

はじめに

この記事は、GAS で Webex Teams bot を作る記事の続編になります。Webex Teams bot の作り方は、下記の記事を参考にしてください。
https://qiita.com/hiroactivity/items/7e319de7821bba36ba4a
ここでは bot に Excel を Multipart で添付して送るサンプルコードを紹介します。

実際の動作

まずはコードの紹介

手っ取り早くコピペで作りたい方のためにまずはコードを紹介します。下記のような感じです。

function sendSpreadsheetAsExcel(){
  // Google Spreadsheet を Excel で取得して Webex に添付してつぶやきます

  // Webex 関連
  const webexToken = "<bot token>"; 
  const webexRoom = "<roomId>"; 
  const webexUrl = 'https://webexapis.com/v1/messages/';

  // google spreadsheet の ID, URL の /d/<この値>/edit? を抜き出す
  const spreadsheetId = 'abcabcabcabc';

  // spreadsheet を Excel で取得するための URL
  const fetchUrl = "https://docs.google.com/feeds/download/spreadsheets/Export?key="+
    spreadsheetId+"&amp;exportFormat=xlsx";

  // OAuth2 設定
  const fetchOpt = {
    "headers": {Authorization: "Bearer " + ScriptApp.getOAuthToken()},
    "muteHttpExceptions": true
  };

  // Excel を blob で取得
  const xlsxFile = UrlFetchApp.fetch(fetchUrl, fetchOpt).getBlob();

  // multipart/form-data のための boundary やヘッダ設定
  const boundary = "myBoundary";

  const headers = {
    'Authorization': 'Bearer ' + webexToken,
    'Content-Type': "multipart/form-data; boundary=" + boundary
  };
  
  // multipart/form-data を作成
  const payload = Utilities.newBlob(
    '--'+boundary+'\r\nContent-Disposition: form-data; name="roomId"\r\n\r\n'+webexRoom+'\r\n' +
    '--'+boundary+'\r\nContent-Disposition: form-data; name="text"\r\n\r\nファイルです!\r\n' +
    '--'+boundary+'\r\nContent-Disposition: form-data; name="files"; filename="myexcel.xlsx"\r\n'+  
        'Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\r\n\r\n').getBytes()
    .concat(xlsxFile.getBytes())
    .concat(Utilities.newBlob('\r\n\r\n--'+boundary+'--\r\n').getBytes()
  );

  const options = {
    'method': 'POST',
    'muteHttpExceptions': true,
    'headers': headers,
    'payload': payload
  };

  res = UrlFetchApp.fetch(webexUrl, options);
  console.log(res.toString());
}

動作結果

上記コードに Bot token, Room ID, Google spreadsheet ID を埋めて GAS で動かしていただくと、下記のように Webex Teams にファイルを添付してつぶやいてくれるはずです。

Screenshot 2024-12-03 at 20.37.36.png

解説

multipart/form-data

今回のメインである GAS で multipart/form-data をどのように送るかの解説です。
Webex API のガイドを見ると、下記のような Python のコードが掲載されています。

参考: https://developer.webex.com/docs/basics

m = MultipartEncoder({'roomId': 'Y2lzY2.....',
                      'text': 'example attached',
                      'files': ('example.png', open('example.png', 'rb'),
                      'image/png')})

今回 GAS で同じことをしようと思ったのですが、GAS では MultipartEncoder のような便利なものは(おそらく)存在しなかったので、自分で作ってみたというのがこの記事の内容になります。ただ上記の Python ではどのように multipart になっているのかわからず、一度 Python でコードを書いて解析しました。その結果、下記のようになっていれば良いようです。これに沿って作ったのが、今回の GAS のコードになります。

--boundary\r\nContent-Disposition: form-data; name="roomdId"<roomId>\r\n
--boundary\r\nContent-Disposition: form-data; name=text"テキストメッセージ\r\n
--boundary\r\nContent-Disposition: form-data; name="files"; filename="任意のファイル名" \r\n
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\r\n\r\n
<ファイルの blob>
\r\n\r\n--boundary--\r\n

ここで、ファイルの blob の後に \r\n を入れるのが重要です。最初これを忘れていてかなりハマりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?