見出し画像

【COZE】Public procurement research

Public procurement researchというCOZE BOTを開発しましたので、その紹介をします。


1.基本動作

・Public procurement researchは、日本の国・独立行政法人、地方公共団体等がホームページ上に掲載している入札情報を提供するCOZE BOTです。
・キーワードを入れることで、直近の入札情報を回答します。

2.工夫した点

・Pluginsであるkkj_pluginを独自開発し、官公需情報ポータルサイト検索APIへ接続を可能にしました。
・官公需情報ポータルサイト検索APIでは、XML形式で結果が出力されますが、COZEのPluginsではXML形式を読み取れません(現状、JSON形式のみを読み取れます)。
・このため、APIリクエストにあたってはGAS(Public procurement research_gas)を経由して行う仕組みにし、官公需APIからのレスポンスをGASでXML形式からJSON形式に変換してから、CozeのPluginsで受け取るようにしました。
・なお、LLMはClaude 3.5 Sonnetを使用することで、大規模のAPIデータをユーザーの求める形にまとめることが可能となりました。
・Public procurement research_gasは次のとおりです。

function doGet(e) {
  // クエリパラメータの取得とデフォルト値の設定
  var query = e.parameter.Query;
  if (!query) {
    return ContentService.createTextOutput("Error: 'Query' parameter is required.").setMimeType(ContentService.MimeType.TEXT);
  }
  
  var count = e.parameter.Count || '1';
  var issueDate = e.parameter.CFT_Issue_Date || '2024-04-01/';

  var url = 'https://www.kkj.go.jp/api/?Query=' + encodeURIComponent(query) + '&Count=' + encodeURIComponent(count) + '&CFT_Issue_Date=' + encodeURIComponent(issueDate);
  var response = UrlFetchApp.fetch(url);
  var xml = response.getContentText();
  
  // XMLをパース
  var document = XmlService.parse(xml);
  var root = document.getRootElement();
  
  // SearchResults要素を取得
  var searchResults = root.getChild('SearchResults');
  if (!searchResults) {
    Logger.log("SearchResults要素が見つかりません。");
    return ContentService.createTextOutput("SearchResults要素が見つかりません。").setMimeType(ContentService.MimeType.TEXT);
  }
  
  // SearchResult要素を取得
  var searchResult = searchResults.getChildren('SearchResult');
  if (searchResult.length === 0) {
    Logger.log("SearchResult要素が見つかりません。");
    return ContentService.createTextOutput("SearchResult要素が見つかりません。").setMimeType(ContentService.MimeType.TEXT);
  }
  
  // データを抽出
  var data = searchResult.map(function(result) {
    var obj = {};
    result.getChildren().forEach(function(child) {
      obj[child.getName()] = child.getText();
    });
    return obj;
  });
  
  // データをログに出力して確認
  Logger.log(JSON.stringify(data));
  
  // スプレッドシートにデータを書き込む
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  // データが存在するか確認
  if (data.length > 0 && Object.keys(data[0]).length > 0) {
    // ヘッダーを取得
    var headers = Object.keys(data[0]);
    
    // 最終行の次の行に書き込む
    var lastRow = sheet.getLastRow();
    
    // ヘッダーが無い場合は追加
    if (lastRow === 0) {
      sheet.appendRow(headers);
      lastRow = 1;
    }
    
    // データを書き込む
    data.forEach(function(row) {
      var values = headers.map(function(header) {
        return row[header];
      });
      sheet.appendRow(values);
    });
    
    // 結果をJSON形式で返す
    return ContentService.createTextOutput(JSON.stringify(data)).setMimeType(ContentService.MimeType.JSON);
  } else {
    Logger.log("データが存在しないか、変換に失敗しました。");
    return ContentService.createTextOutput("データが存在しないか、変換に失敗しました。").setMimeType(ContentService.MimeType.TEXT);
  }
}

3.その他

・このCOZE BOTは、COZE公式DiscordサイトによるCoze July AI Bot ChallengeにてMost creative botsに選定されました。
・The #AI -chatbot Writing Contest by Coze & HackerNoonに参加しています。

いいなと思ったら応援しよう!