Chatwork APIでファイル名に日本語が含まれるファイルをアップロードすると文字化けする問題を解決した話

※最後まで無料で読めます!

はじめに

会社で主に使われているチャットツールがChatworkなんですが、一斉送信や予約送信が標準機能として実装されていないのが個人的にネックだと思っていました。
調べてみると、APIを使えばそれらが可能になると知り、早速GASでトライ。

ChatWorkClientというライブラリがあるそうで、これを追加すればあ~ら簡単!
でもファイルのアップロードはできない模様…直接APIを叩くしかないということか。
どうせならGoogleドライブに保存されているファイルをアップロードできるようにしたいと思い、さらに調べてみた結果。

思いの外パラメータがあっさりしている…!?
過去にNotion APIで苦戦した記憶が蘇るところでしたが、一安心。
これで毎月の請求書や報酬明細の送信作業が楽になるぜ~✌️
と小躍りしていたのも束の間。

ファイル名が文字化けしとるやんけ…。

ググればなんとかなるやろ、と思いきや…

色んな検索クエリで検索してみるも、該当する記事がなかなかヒットしない…。
なんなら

  • 日本語のファイル名は文字化けするので、ファイル名に日本語を使わないようにしている。

  • 色々試してみたけど、どうしても日本語が文字化けしちゃう…原因調査中。

と、同じ問題で悩んでいる記事がほとんど。
加えて公式ドキュメントにも、それらしき記載が見当たらない。

だからってできないわけないやろ!!
納得いかねー!!

解決策

なんだか腹が立って仕方がないので、血眼になって調べまくった結果。

めちゃくちゃ参考になる記事を見つけることができました。
上記の記事のコードをもとに、Chatwork用にいじったものがこちら。

function sendMessage() {

  // ----------省略----------

  // ファイルIDからファイル名とBlob形式のファイルを取得
  const file_name = DriveApp.getFileById(file_id).getName() // ファイル名
  const file = DriveApp.getFileById(file_id).getBlob(); // ファイル

  const boundary = "boundary"; // 添付ファイル情報の境界となる文字
  const lineBreak = "\r\n"; // 改行文字
  const encodedName = encodeURIComponent(file_name); // ファイル名をエンコード

  // リクエストボディを生成
  const blobByte = Utilities.newBlob(
    "--" + boundary + lineBreak
    // メッセージ
    + "Content-Disposition: form-data; name=\"message\"" + lineBreak + lineBreak
    + message + lineBreak
    + "--" + boundary + lineBreak // フォームの区切りを付与
    // ファイルデータ(※ファイル名の文字コードにUTF-8を指定)
    + "Content-Disposition: form-data; name=\"file\"; filename=\"" + file_name + "\"; filename*=UTF-8\'\'" + encodedName + lineBreak
    + "Content-Type: " + file.getContentType() + lineBreak + lineBreak
  ).getBytes().concat(
    file.getBytes() // ファイルの情報を付加
  ).concat(
    Utilities.newBlob(lineBreak + "--" + boundary + "--").getBytes() // 最後の区切りを付加
  );
     
  const url = "https://api.chatwork.com/v2/rooms/" + room_id + "/files"; // エンドポイントの設定

  // HTTPリクエストのメソッドとパラメータを設定
  const options = {
    "method": "POST",
    "headers": {
      "accept": "application/json",
      "content-type": "multipart/form-data; boundary=" + boundary,
      "x-chatworktoken": token,
    },
    "payload": blobByte,
    "muteHttpExceptions": true,
    "validateHttpsCertificates": false,
    "followRedirects": false,
  };

  try {
    // Chatwork APIへリクエストする
    let response = UrlFetchApp.fetch(url, options);
    response = JSON.parse(response.getContentText());
    Logger.log(response);
  } catch(e) {
    // 例外エラー処理
    Logger.log('Error:');
    Logger.log(e);
  }

  // ----------省略----------

}

実行してみたところ、

できるやんけ~~~!!

おわりに

そもそもBlobとかmultipart/form-dataとか今まで全然知らなかったんですけど、勉強になりました。
この記事が誰かの一助になれば幸いです。

ここから先は

0字

¥ 100

この記事が気に入ったらチップで応援してみませんか?