別アプリへ添付ファイルをコピーしたい

Aというアプリにはチェックボックスがあり、その値に応じて処理を行います。

  • チェックボックスの値が「1」の場合:
    テーブル内の添付ファイルを、Bというアプリの「1添付ファイル」フィールドに転記します。
  • チェックボックスの値が「2」の場合:
    テーブル内の添付ファイルを、Bというアプリの「2添付ファイル」フィールドに転記します。

いずれの場合も、Aのアプリ内の「氏名」とBのアプリの「氏名」フィールドが一致するレコードに対して処理を実行します。

このような処理を実現できるプラグインやJavaの実装方法があれば教えてください。

ここらへんの回答が参考になりそうですね

  1. プラグインの紹介
    【キントーン】添付ファイルを別アプリにコピーしたい

  2. カスタマイズの実装方法について
    添付ファイルを同じアプリ内の添付ファイルフィールドにコピーしたい

今回はチェックボックスに応じて動きを動的にしたいということなので独自でのカスタマイズが必要そうにはみえますが

まず、添付ファイルのコピーは普通に書くと、かなりややこしい
記述になるため、kintone REST API Client の利用をお勧めします。

質問者の要件を十全に満たす内容ではないですが、今たまたま「別アプリの
特定のフィールドが一致するレコードに添付ファイルをコピーする」という
大筋は共通したことをやっていたところなので、そのコードを公開します。

チェックボックスの値に基づく条件分岐を作るのは
それほど難しくはないので、これを叩き台にすればできるかと思います。

前提として kintone REST API Client の CDN の URL
このコードよりも上に配置する必要があります。

(async () => {
  "use strict";
  const client = new KintoneRestAPIClient();

  // アプリAのレコード追加画面か編集画面で保存が成功したときに処理を開始
  kintone.events.on([
    "app.record.create.submit.success",
    "app.record.edit.submit.success"
  ], async (event) => {
    
    // ルックアップの[氏名]が参照するアプリのアプリIDを取得
    const appBId = kintone.app.getLookupTargetAppId("氏名");
    // 取得できなかった場合は処理を中断
    if (!appBId) {
      alert("[氏名]の参照先のアプリIDを取得できませんでした。");
      return event;
    }

    // 保存が成功したレコードの情報を取得
    const recordA = event.record;
    const identity = recordA["氏名"].value;
    const filesA = recordA["添付ファイル"].value;

    // [氏名]が未入力の場合は処理を中断
    if (!identity) {
      return event;
    }
    
    // [添付ファイル]に何もアップロードされていない場合は処理を中断
    if (!filesA.length) {
      return event;
    }

    try {
      // 参照先のアプリBから[氏名]が一致するレコードを検索
      const recordsB = await client.record.getRecords({
        app: appBId,
        query: `氏名 = "${identity}"`,
      });

      // 検索結果がなかった場合は処理を中断して警告を表示
      if (!recordsB.records.length) {
        alert(`[氏名]が ${identity} のレコードがアプリBにありませんでした。`);
        return event;
      }

      // 検索結果の1件目のレコードのIDを取得(アプリBの[氏名]に一意制約があるのが前提)
      const recordBId = recordsB.records[0].$id.value;

      const fileKeys = await Promise.all(
        filesA.map(async (file) => {
          
          // アプリAの[添付ファイル]をダウンロード
          const fileBlob = await client.file.downloadFile({ fileKey: file.fileKey });
          
          // ダウンロードしたファイルをアプリBの[添付ファイル]へアップロード
          const uploadedFile = await client.file.uploadFile({
            file: {
              name: file.name,
              data: fileBlob,
            },
          });

          return { fileKey: uploadedFile.fileKey };
        })
      );

      // ファイルをアップロードしたレコードを更新
      await client.record.updateRecord({
        app: appBId,
        id: recordBId,
        record: {
          添付ファイル: {
            value: fileKeys,
          },
        },
      });
    
    } catch (error) {
      // エラー発生時はアラートを表示し、詳細情報をコンソールに出力
      alert("エラーが発生しました。詳細はコンソールを確認してください。");
      console.error("エラーが発生しました:", error);
    }

    return event;
  });
})();
3 Likes

ご回答いただき有難うございます。参考にさせていただきます :bowing_woman:

まさしく、私のやりたいことに類似しています!
有難うございます。活用させていただきます :pray:

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。