キーワードとの一致をAIで分岐するのと、同じ様なスクリプトの問題

キーワード分岐するAI-Studioを、AIクレジットの節約のため、スクリプトに変更を試みました。スクリプトへの変換は、Asana-AIに頼みました。


AI-StudioのAIへのガイダンス:正常に機能します。

  • タスクの類似性確認ガイドライン 目的:このガイドラインは、新規タスクの類似性を評価し、適切な対応を行うための手順を定めます。これにより、タスクを分類し、効率的なタスク管理を目指します。
    手順:1. 新規タスクの確認: 新規タスクの「名前」と「説明」の内容を詳しく確認してください。2. 含まれる文字列と、下記の「分類キーワード」との類似性を評価します。
    分類キーワード:・キーワード安全衛生交通:安全、衛生、災害、ケガ、不休、休業、救急車、消防車 ・キーワード品質:不良、不適合、トラブル、仕損、故障
    対応方法:1. 類似性が「安全衛生交通」の場合: カスタムフィールド”連絡事項の区分”を”安全衛生交通”にする 2. 類似性が「品質」の場合: カスタムフィールド”連絡事項の区分”を”品質”にする 3. 類似性が無い場合: カスタムフィールド”連絡事項の区分”を”総務ほか”にし、コメントに理由を記入する

変換したスクリプト:エラーで機能しません。

  • async function run() {
    // カスタムフィールドGIDの設定
    // 取得方法: プロジェクトのカスタマイズメニュー > フィールド から確認できます
    const customFieldGid = “YOUR_CUSTOM_FIELD_GID”;

    // カテゴリ名とカスタムフィールド選択肢のGIDをマッピング
    // 各選択肢のGIDはAPIレスポンスから取得できます
    const categoryGidMap = {
    “安全衛生交通”: “GID_OF_SAFETY_CATEGORY”,
    “品質”: “GID_OF_QUALITY_CATEGORY”,
    “総務ほか”: “GID_OF_OTHER_CATEGORY”
    };

    // 分類キーワード定義(優先度順)
    const KEYWORDS = {
    “安全衛生交通”: [“安全”, “衛生”, “災害”, “ケガ”, “不休”, “休業”, “救急車”, “消防車”, “交通”, “事故”],
    “品質”: [“不良”, “不適合”, “トラブル”, “仕損”, “故障”, “クレーム”, “品質”]
    };
    /**

    • タスクの類似性を評価し、カスタムフィールドの選択肢GIDを返す関数
    • @param {string} taskName タスク名
    • @param {string} taskDescription タスクの説明
    • @returns {string} マッチしたカテゴリのGID、またはデフォルトのGID
      */
      function evaluateTaskSimilarity(taskName, taskDescription) {
      // タスク内容を結合
      const content = (taskName + " " + (taskDescription || “”));
      // 各カテゴリのキーワードとの一致を確認
      for (const [category, keywordList] of Object.entries(KEYWORDS)) {
      for (const keyword of keywordList) {
      if (content.includes(keyword)) {
      log(キーワード「${keyword}」が見つかりました。「${category}」に分類します。);
      return categoryGidMap[category];
      }
      }
      }
      // 一致するキーワードがない場合は、「総務ほか」のGIDを返す
      log(“キーワードが見つかりませんでした。「総務ほか」に分類します。”);
      return categoryGidMap[“総務ほか”];
      }
      try {
      // タスクデータを取得
      const task = await tasksApiInstance.getTask(task_gid);
      log("タスク名: " + task.data.name);
      // 類似性評価(カスタムフィールドのGIDを取得)
      const customFieldOptionGid = evaluateTaskSimilarity(task.data.name, task.data.notes);
      // カスタムフィールドを更新
      await tasksApiInstance.updateTask(task_gid, {
      data: {
      custom_fields: {
      [customFieldGid]: customFieldOptionGid
      }
      }
      });
      // 「総務ほか」に分類された場合はコメントを追加
      if (customFieldOptionGid === categoryGidMap[“総務ほか”]) {
      await tasksApiInstance.createComment(task_gid, {
      data: {
      text: “キーワードとの類似性が見つからなかったため、「総務ほか」に分類しました。必要に応じて手動で変更してください。”
      }
      });
      }
      log(タスク「${task.data.name}」の区分を更新しました);
      } catch (error) {
      log("エラーが発生しました: " + error.message);
      log("エラー詳細: " + JSON.stringify(error));
      }
      }
      // スクリプトを実行
      run();

実行結果は、成功とは書いてありますが、実際はエラーと書いてあるようです。

  • タスク名: WBGT31℃【危険】本日(9 / 2)の暑さ指数配信…
    キーワード「安全」が見つかりました。「安全衛生交通」に分類します。
    エラーが発生しました: Cannot read properties of undefined (reading ‘hasOwnProperty’)
    エラー詳細: {“name”:“TypeError”,“message”:“Cannot read properties of undefined (reading ‘hasOwnProperty’)”}
    Finished in 403 ms.

スクリプトの修正のアドバイスを頂けないでしょうか?

1 Like

コードを書いていてよくやるのですが、エラーコードをそのままAIに与えて、スクリプトを修正してもらったり、原因を教えてもらったりします。

asana AIにエラーを投げてみるとどうなりますか?

2 Likes

@Tetsuo_Kawakami さん コメントありがとうございます。

Asana_AIに聞いてみました。

1)依頼:次のスクリプトが問題あるかどうか確認してください。

  • AIの回答:このスクリプトを確認しました。全体的に問題ありませんが、いくつかの注意点と改善点があります。
    スクリプトの評価
  1. プレースホルダーの置き換え
  • YOUR_CUSTOM_FIELD_GIDGID_OF_SAFETY_CATEGORYなどのプレースホルダーは実際の値に置き換える必要があります
  • これらを置き換えないとスクリプトは正常に動作しません
  1. 未定義変数
  • task_gidtasksApiInstancelog関数が定義されていません
  • これらは外部から提供されることを前提としているようです
  1. エラーハンドリング
  • エラーハンドリングは適切に実装されています
  1. 機能面
  • キーワードベースの分類ロジックは単純ですが効果的です
  • 「総務ほか」がデフォルトカテゴリとして適切に設定されています

改善提案

  1. スクリプトの先頭で必要な変数(task_gidなど)を定義する
  2. キーワードマッチングで大文字/小文字を区別しない処理を追加する
  3. APIインスタンスの初期化コードを含める

このスクリプトは、タスク内容に基づいて自動的にカテゴリ分類するための基本的な機能を備えています。プレースホルダーを適切な値に置き換え、未定義変数を定義すれば問題なく動作するでしょう。


2)依頼:実行結果(下記)を説明してください。「タスク名: WBGT31℃【危険】本日(9 / 2)の暑さ指数配信…キーワード「安全」が見つかりました。「安全衛生交通」に分類します。エラーが発生しました: Cannot read properties of undefined (reading ‘hasOwnProperty’)エラー詳細: {“name”:“TypeError”,“message”:“Cannot read properties of undefined (reading ‘hasOwnProperty’)”}Finished in 403 ms.

  • AIの回答:実行結果を分析すると、スクリプトが部分的に動作した後にエラーが発生していることがわかります。

実行結果の説明

  1. 正常に動作した部分:
  • タスク名「WBGT31℃【危険】本日(9 / 2)の暑さ指数配信…」の取得に成功

  • キーワード「安全」を検出し、「安全衛生交通」カテゴリに正しく分類

  1. エラー内容:
  • Cannot read properties of undefined (reading 'hasOwnProperty')

  • このエラーは、存在しないオブジェクトのプロパティにアクセスしようとした際に発生

  1. エラーの原因:
  • APIレスポンスの構造が想定と異なる可能性があります

  • custom_fieldsオブジェクトの扱い方に問題がある可能性が高い

考えられる具体的な問題点:

  1. カスタムフィールドGIDが正しく設定されていない

  2. tasksApiInstance.updateTaskの呼び出し方法が間違っている

  3. カスタムフィールドの更新構文が間違っている

修正案:

// カスタムフィールドの更新部分を修正
await tasksApiInstance.updateTask(task_gid, {
data: {
custom_fields: {
customFieldGid: customFieldOptionGid
}
}
});

を以下のように変更:

// カスタムフィールドの更新部分を修正
await tasksApiInstance.updateTask(task_gid, {
data: {
custom_fields: {
customFieldGid: customFieldOptionGid
}
}
});

エラーが発生した時点で処理が中断されたため、コメント追加などの後続処理は実行されていません。まずはAPIの仕様を確認し、カスタムフィールド更新の構文を修正することをお勧めします。


3)依頼:次のAsanaスクリプトが問題あるかどうか確認してください。問題が有る箇所の修正案を教えてください。

  • AIの回答:
    このAsanaスクリプトを確認しました。いくつかの問題点と修正案を以下に示します。

問題点と修正案

  1. 未定義変数の問題

// 問題: task_gid が定義されていない

const task = await tasksApiInstance.getTask(task_gid);

// 修正案: スクリプトの先頭で定義する

const task_gid = context.task_gid; // または適切な方法で取得

  1. APIインスタンスの問題

// 問題: tasksApiInstance が定義されていない

const task = await tasksApiInstance.getTask(task_gid);

// 修正案: Asana APIクライアントを初期化する

const asana = require(‘asana’);

const client = asana.Client.create().useAccessToken(process.env.ASANA_ACCESS_TOKEN);

const tasksApiInstance = client.tasks;

  1. ログ関数の問題

// 問題: log 関数が定義されていない

log(キーワード「${keyword}」が見つかりました。「${category}」に分類します。);

// 修正案: ログ関数を定義する

function log(message) {

console.log(message);

}

  1. カスタムフィールド更新の構文問題

// 問題: カスタムフィールド更新の構文が原因でエラーが発生している可能性

await tasksApiInstance.updateTask(task_gid, {

data: {

custom_fields: {

}

}

});

// 修正案: Asana APIの正しい構文に修正

await tasksApiInstance.updateTask(task_gid, {

custom_fields: {

}

});

  1. プレースホルダーの問題

// 問題: プレースホルダーが実際の値に置き換えられていない

const customFieldGid = “YOUR_CUSTOM_FIELD_GID”;

const categoryGidMap = {

“安全衛生交通”: “GID_OF_SAFETY_CATEGORY”,

// …

};

// 修正案: 実際の値に置き換える

const customFieldGid = “1234567890”; // 実際のGIDに置き換え

const categoryGidMap = {

“安全衛生交通”: “1111111111”, // 実際のGIDに置き換え

“品質”: “2222222222”, // 実際のGIDに置き換え

“総務ほか”: “3333333333” // 実際のGIDに置き換え

};

  1. 大文字小文字の区別問題

// 問題: キーワード検索で大文字小文字を区別している

if (content.includes(keyword)) {

// 修正案: 大文字小文字を区別しないように修正

if (content.toLowerCase().includes(keyword.toLowerCase())) {

これらの修正を適用することで、スクリプトが正常に動作する可能性が高まります。特に、エラーメッセージ「Cannot read properties of undefined (reading ‘hasOwnProperty’)」は、カスタムフィールド更新の構文が間違っているか、APIレスポンスの構造が想定と異なることが原因と考えられます。

1 Like

@Ka_Nishiyama さん

Script Actions の事例投稿ありがとうございます!

AIにスクリプトを書かせても、そのままでは使えないことが多いですね。

まずは、コードの上の方を確認しましたが、コメント通りに YOUR_CUSTOM_FIELD_GID や GID_OF_SAFETY_CATEGORY を書き換えてコードを実行されていますでしょうか?

取得方法: プロジェクトのカスタマイズメニュー > フィールド から確認できます

とありますが、カスタムフィールドのGIDは実際にはUI上で確認できないため、custom_field_settings などを確認する必要があります。

一般的なガイドとして、

  • こまめにログを取って、各変数が持っている値を確認する

  • エラーが出ている行番号を確認して、それを中心に確認する

などが有効です。

ログの取り方としては、

  • log関数を使用する(ルール編集とタスク操作のためにそれぞれ別のブラウザータブを開くと便利です)

  • Asanaタスクにコメントを投稿する

などの方法があります。

最初に確認していただく項目としてご参考になれば幸いです。

1 Like

AsanaAIに何度も修正を依頼した結果、スクリプトは下記となりました。

/**

  • キーワードで分岐してカスタムフィールドを変更する
  • AI-Studioで実行するスクリプト
    */
    async function run() {
    // ログ出力関数
    function log(message) {
    console.log(message);
    }

// Asana APIクライアントの初期化
const asana = require(‘asana’);
const client = asana.Client.create().useAccessToken(process.env.ASANA_ACCESS_TOKEN);
const tasksApiInstance = client.tasks;

// タスクIDの取得と確認
const task_gid = context.task_gid;
if (!task_gid) {
log(“エラー: タスクIDが見つかりません”);
return;
}

// カスタムフィールドGIDの設定
const customFieldGid = “1211190712762357”; // 「連絡事項の区分」のGID

// カテゴリ名とカスタムフィールド選択肢のGIDをマッピング
const categoryGidMap = {
“安全衛生交通”: “1211190712762358”,
“品質”: “1211190712762359”,
“総務ほか”: “1211190712762360”
};

// 分類キーワード定義(優先度順)
const KEYWORDS = {
“安全衛生交通”: [“安全”, “衛生”, “災害”, “ケガ”, “不休”, “休業”, “救急車”, “消防車”, “交通”, “事故”],
“品質”: [“不良”, “不適合”, “トラブル”, “仕損”, “故障”, “クレーム”, “品質”]
};

/**

  • タスクの類似性を評価し、カスタムフィールドの選択肢GIDを返す関数
  • @param {string} taskName タスク名
  • @param {string} taskDescription タスクの説明
  • @returns {string} マッチしたカテゴリのGID、またはデフォルトのGID
    */
    function evaluateTaskSimilarity(taskName, taskDescription) {
    // タスク内容を結合
    const content = (taskName + " " + (taskDescription || “”));
// 各カテゴリのキーワードとの一致を確認
for (const [category, keywordList] of Object.entries(KEYWORDS)) {
  for (const keyword of keywordList) {
    if (content.toLowerCase().includes(keyword.toLowerCase())) {
      log(`キーワード「${keyword}」が見つかりました。「${category}」に分類します。`);
      return categoryGidMap[category];
    }
  }
}

// 一致するキーワードがない場合は、「総務ほか」のGIDを返す
log("キーワードが見つかりませんでした。「総務ほか」に分類します。");
return categoryGidMap["総務ほか"];

}

try {
// タスクデータを取得
const task = await tasksApiInstance.getTask(task_gid);

// データ構造を確認
log("タスク構造: " + JSON.stringify(task));
const taskName = task.name || (task.data && task.data.name) || "";
const taskNotes = task.notes || (task.data && task.data.notes) || "";
log("タスク名: " + taskName);

// 類似性評価
const customFieldOptionGid = evaluateTaskSimilarity(taskName, taskNotes);

// カスタムフィールドを更新
await client.tasks.update(task_gid, {
  custom_fields: {
    [customFieldGid]: customFieldOptionGid
  }
});

// 更新後の確認
const updatedTask = await client.tasks.getTask(task_gid);
log("更新後のカスタムフィールド値: " + JSON.stringify(updatedTask.custom_fields));

// 「総務ほか」に分類された場合はコメントを追加
if (customFieldOptionGid === categoryGidMap["総務ほか"]) {
  await client.stories.createStoryForTask(task_gid, {
    text: "キーワードとの類似性が見つからなかったため、「総務ほか」に分類しました。必要に応じて手動で変更してください。"
  });
}

log(`タスク「${taskName}」の区分を更新しました`);

} catch (error) {
log("エラーが発生しました: " + error.message);
log("エラー詳細: " + JSON.stringify(error));
}
}

// スクリプトを実行


AsanaAIは、これで問題ないとのことですが、
実行してもうまく行きません。
実行履歴は「No log found.」となってます。

1 Like

一度下のリンクを一通り読んでから、始めると修正しやすいと思います。

1 Like

次のコードはいらないと思います。

  • // ログ出力関数
    function log(message) {
    console.log(message);
    }

// Asana APIクライアントの初期化
const asana = require(‘asana’);
const client = asana.Client.create().useAccessToken(process.env.ASANA_ACCESS_TOKEN);
const tasksApiInstance = client.tasks;

// タスクIDの取得と確認
const task_gid = context.task_gid;
if (!task_gid) {
log(“エラー: タスクIDが見つかりません”);
return;
}

また、

// カスタムフィールドを更新
await client.tasks.update(task_gid, {
custom_fields: {
[customFieldGid]: customFieldOptionGid
}
});

await tasksApiInstance.update(task_gid,
{
“data”: {
“custom_fields”: {
customFieldGid : customFieldOptionGid
}
}
});

のようにする必要がありそうですね。

参考: Custom fields

また、上のコードを

const updatedTask = await tasksApiInstance.update(task_gid,
{
“data”: {
“custom_fields”: {
customFieldGid : customFieldOptionGid
}
}
});

とすると

const updatedTask = await client.tasks.getTask(task_gid);

は不要です。

また、

log("更新後のカスタムフィールド値: " + JSON.stringify(updatedTask.custom_fields));

log("更新後のカスタムフィールド値: " + JSON.stringify(updatedTask.data.custom_fields));

とする必要があると思います。

AI studioはJavaScriptという言語で書くので、JavaScriptについても簡単に学んでおくと、修正の役に立つと思います。

1 Like

皆さん、色々ありがとうございます。
スクリプトは、難しいですね。

今朝、改めてAsanAIに聞いてみたのですが、スクリプトでは、AI-Studioと同じ様なキーワードからの曖昧な類推一致比較は、出来ないとのことでした。


Asana-AI との質疑1

  • 問合せ:スクリプトについて タスクの説明を読んで、指定したキーワードと比較し類似性が有るか無いか、判断することが出来ますか?
  • AI回答:
    Asana AIの機能について
    現在のAsanaの標準機能では、タスクの説明を読んで指定したキーワードと自動的に比較し類似性を判断する直接的な機能はありません。ただし、以下のAsana AI機能が関連するかもしれません:
    Smart answers: 自然言語でAsanaに質問し、プロジェクトに関する回答やインサイトを得ることができます
    Smart summaries: タスクの説明やコメントからハイライトを抽出し、要約することができます
    検索機能: 特定のキーワードを含むタスクを検索することは可能です
    自動化オプション
    タスク内容の分析には、以下の方法が考えられます:
    -1. Rules機能: 特定の条件に基づいてタスクを自動的に処理できますが、テキスト内容の類似性分析は現在の標準機能には含まれていません
    -2. Smart rules: AIを使って自然言語の指示でルールを作成できます(Advanced/Enterprise向け機能)

Asana-AI との質疑2

  • 問合せ:スクリプトでAI機能にアクセス出来ますか?
  • AI回答: スクリプトとAsana AI機能の連携について
    はい、AsanaのAPIを通じてスクリプトからAsanaにアクセスすることは可能ですが、現在のドキュメントではAI機能に特化したAPI連携については明確に記載されていません。
    Asana APIでは以下のことが可能です:
    Asana内の情報の読み取り
    – 外部からの情報入力
    – 変更があった際の自動反応
    ただし、Smart summaries、Smart editor、Smart chatなどのAI機能に直接スクリプトからアクセスする方法については、現在の公開ドキュメントでは詳細が提供されていません。
2 Likes

@Ka_Nishiyama

勉強のために、ちょっといじってみました。私の環境で動作するのを確認しました。

安全衛生交通については、割愛しました。必要であれば追加してください。

以下のコードで当初貼り付けておられたコードでやりたいことはできると思います。

おっしゃるように、 AI Studioのように曖昧な類推比較はできないと思います。Nodejsにそう言った機能が追加されたら、できるようになるかもしれませんが。

async function run() {
  // Anything else you want to do!
  // カスタムフィールドGIDの設定
  const customFieldGid = "123456"; // 「連絡事項の区分」のGID

  // カテゴリ名とカスタムフィールド選択肢のGIDをマッピング
  const categoryGidMap = {
    "品質": "1234567", // 実際のGIDに書き換える
    "総務ほか": "12345678" // 実際のGIDに書き換える
  };
  
  // 分類キーワード定義(優先度順)
  const KEYWORDS = {
    "品質": ["不良", "不適合", "トラブル", "仕損", "故障", "クレーム", "品質"]
  }

  // タスクの類似性を評価し、カスタムフィールドの選択肢GIDを返す関数
  function evaluateTaskSimilarity(taskName, taskDescription) {
    // タスク内容を結合
    const content = (taskName + ""  + (taskDescription || ""));
    // 各カテゴリのキーワードとの一致を確認
    for (const [category, keywordList] of Object.entries(KEYWORDS)) {
      for (const keyword of keywordList) {
        if (content.toLowerCase().includes(keyword.toLowerCase())) {
          log(`キーワード「${keyword}」が見つかりました。「${category}」に分類します。`);
          return categoryGidMap[category];
        }
      }
    }
    // 一致するキーワードがない場合は、「総務ほか」のGIDを返す
    log("キーワードが見つかりませんでした。「総務ほか」に分類します。");
    return categoryGidMap["総務ほか"];
  }

  try{
    // タスクデータを取得
    const task = await tasksApiInstance.getTask(task_gid);
    // データ構造を確認
    log("タスク構造: " + JSON.stringify(task, null, 2));
    const taskName = task.name || (task.data && task.data.name) || "";
    const taskNotes = task.notes || (task.data && task.data.notes) || "";
    log("タスク名: " + taskName + "説明:" + taskNotes);
    
    // 類似性評価
    const customFieldOptionGid = evaluateTaskSimilarity(taskName, taskNotes);
    
    // カスタムフィールドを更新
    let body = {
      "data":{
        "custom_fields":{
          [customFieldGid]: customFieldOptionGid
        }
      }
    }
    await tasksApiInstance.updateTask(body, task_gid);
    
    // 更新後の確認
    const updatedTask = await tasksApiInstance.getTask(task_gid);
    log("更新後のカスタムフィールド値: " + JSON.stringify(updatedTask, null, 2));

    
    
    // 「総務ほか」に分類された場合はコメントを追加
    body = {
      "data": {
        "text": "キーワードとの類似性が見つからなかったため、「総務ほか」に分類しました。必要に応じて手動で変更してください。"
      }
    }

    if (customFieldOptionGid === categoryGidMap["総務ほか"]) {
      await storiesApiInstance.createStoryForTask(body, task_gid);
    }
    
    log(`タスク「${taskName}」の区分を更新しました`);
    
  }catch(error){
    log("エラーが発生しました: " + error.message);
    log("エラー詳細: " + JSON.stringify(error, null, 2));    
  }
}

// To function properly, the script must end with returning a Promise via run().
run();

最後に、geminiに書き直してもらいました。

// スクリプト全体で共通して使用する定数
const customFieldGid = "123456"; // 「連絡事項の区分」のGID

const categoryGidMap = {
  "品質": "1234567",
  "総務ほか": "12345678"
};

const KEYWORDS = {
  "品質": ["不良", "不適合", "トラブル", "仕損", "故障", "クレーム", "品質"]
};

// --- ユーティリティ関数 ---

/**
 * タスクの類似性を評価し、カスタムフィールドのGIDを返す
 * @param {string} taskName - タスク名
 * @param {string} taskDescription - タスクの説明
 * @returns {string} - カスタムフィールド選択肢のGID
 */
function evaluateTaskSimilarity(taskName, taskDescription) {
  const content = `${taskName} ${taskDescription || ""}`;
  
  for (const [category, keywordList] of Object.entries(KEYWORDS)) {
    for (const keyword of keywordList) {
      if (content.toLowerCase().includes(keyword.toLowerCase())) {
        log(`キーワード「${keyword}」が見つかりました。「${category}」に分類します。`);
        return categoryGidMap[category];
      }
    }
  }
  
  log("キーワードが見つかりませんでした。「総務ほか」に分類します。");
  return categoryGidMap["総務ほか"];
}

/**
 * タスクのカスタムフィールドを更新する
 * @param {string} taskId - タスクGID
 * @param {string} customFieldOptionGid - 更新するカスタムフィールドの選択肢GID
 */
async function updateTaskCustomField(taskId, customFieldOptionGid) {
  const body = {
    "data": {
      "custom_fields": {
        [customFieldGid]: customFieldOptionGid
      }
    }
  };
  await tasksApiInstance.updateTask(body, taskId);
  
  const updatedTask = await tasksApiInstance.getTask(taskId);
  log("更新後のカスタムフィールド値: " + JSON.stringify(updatedTask, null, 2));
}

/**
 * 「総務ほか」に分類された場合にコメントを投稿する
 * @param {string} taskId - タスクGID
 * @param {string} customFieldOptionGid - 設定されたカスタムフィールドの選択肢GID
 */
async function postCommentIfNecessary(taskId, customFieldOptionGid) {
  if (customFieldOptionGid === categoryGidMap["総務ほか"]) {
    const commentBody = {
      "data": {
        "text": "キーワードとの類似性が見つからなかったため、「総務ほか」に分類しました。必要に応じて手動で変更してください。"
      }
    };
    await storiesApiInstance.createStoryForTask(commentBody, taskId);
  }
}

// --- メインの実行関数 ---
async function run() {
  try {
    // 1. タスクデータを取得
    const task = await tasksApiInstance.getTask(task_gid);
    log("タスク構造: " + JSON.stringify(task, null, 2));
    
    // 2. タスク名と説明を取得し、ない場合は空文字を代入
    const taskName = task.name || (task.data && task.data.name) || "";
    const taskDescription = task.notes || (task.data && task.data.notes) || "";
    log(`タスク名: ${taskName}\n説明: ${taskDescription}`);
    
    // 3. 類似性を評価してカスタムフィールドの選択肢を特定
    const customFieldOptionGid = evaluateTaskSimilarity(taskName, taskDescription);
    
    // 4. カスタムフィールドを更新
    await updateTaskCustomField(task_gid, customFieldOptionGid);
    
    // 5. 「総務ほか」に分類された場合にコメントを追加
    await postCommentIfNecessary(task_gid, customFieldOptionGid);
    
    log(`タスク「${taskName}」の区分を更新しました。`);
    
  } catch (error) {
    log("エラーが発生しました: " + error.message);
    log("エラー詳細: " + JSON.stringify(error, null, 2));
  }
}

// To function properly, the script must end with returning a Promise via run().
run();

1 Like

Asana AIはAsana用にチューニングしていると思うので、スクリプトアクション用のスクリプトも素直に出力するようにしてほしいですね😭

2 Likes

@Tetsuo_Kawakami さん、ありがとうございます。

今、試してみました。
うまく、動いてる様です。

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.