• 車種別
  • パーツ
  • 整備手帳
  • ブログ
  • みんカラ+

ヒデノリのブログ一覧

2025年09月01日 イイね!

ネクストエンジンとGoogleスプレッドシートをAPI接続できるGASの開発

ネクストエンジンとGoogleスプレッドシートをAPI接続できるGASの開発途中まで書いて愚痴のブログになったので、
お時間の有る方のみお付き合いくださいm(_ _)m

その中でもAIについて記述している部分がありますので、
その内容が貴方の日々のビジネスやプライベートで有用になることを願います。

2週間ほど前からタイトルの課題に取り組んでいました。

我が社ではOrder Management System=OMSとしてネクストエンジン、
データの共有としてGoogleスプレッドシートを使用しておりますが、
その接続方法が課題でした。

と言っても、課題だと思うのは我が社で私だけ(-_-;)

人力でネクストエンジンからCSVをダウンロードして、
Googleスプレッドシートにアップロードするという方法が簡単に行えそうですが、
私からするとその作業を1日何回行うのですか?
例えば1日3回だとして360日稼働だとして1年で1080回ですよね?
10年行ったとしたら10800回ですよね?
その人件費は経費ベースだとそこまで多くないかもしれませんが、
人時生産性ベースだといくらかわかりますか?

そういうのがわからないのが我が社でとても残念な点だと思います。
ほんまたいがいやな~(-_-;)

楽天のとある部門で一位とか偉そうに言っていますが、
うちの会社はホンマに何も出来てませんよ。
なので私の仕事が無限にあるという(笑)

以前使用していたTepsは価格が暴騰して使用を止めました(-_-;)
Tepsも良かったのですが、
出来ないこともありましたんでGASでのスケジュールで実現したことはあります。

7月末に見つけて8月頭から少し使用したYoomは思う動作ではなかったので、
ネクストエンジン側の接続を遮断しました。

それよりまだ前に使用していたのは、
我が社にSFTPサーバーを立ち上げて、
(その中にNO-IPという技術が入っています)
ネクストエンジンからSFTPサーバーに対してCSVを時間指定で吐き出させる
という事をしていました。

そのCSVをGoogleドライブに連携させて、
GoogleスプレッドシートにGoogle Apps Script=GASでCSVを読み込ませる
というのを時間指定して処理させていました。

ですが、ネクストエンジンがCSVを吐き出させるスケジュールが
スケーラビリティに優れていない・・・(-_-;)

ということで、AIに
ネクストエンジンとGoogleスプレッドシートを接続する方法を教えてもらえますか?
と聞くと、
Yoomという回答もあったのですが、
ハードルは高くなるもののGASでの開発ならばスケーラビリティに優れている
という回答を得られましたのでGASでの開発にシフトしていきました。

と言うものの、
GASを最初から学ぶには今年49歳という年齢からあまりにも遅すぎる・・・

なので、令和の今どきであるコーディングが出来るAIに頼ることにしました(笑)

当然、我が社にはAIに払う予算なんてものは存在しませんし、
会議でAIは・・・
なんて言おうものなら上層部に頭の硬い連中がいるので、
AIというのも・・・
なんて超絶めんどくさい事を言う奴しか居ないので
報告無しで無料枠からAIを使うしかありませんでした。

私の人生のコンセプトは仕事の課題は仕事の時間中のみ。
ただし、プライベートでその課題が気になるのは仕方ない。
ですが、仕事とプライベートは基本的に割り切る。

コーディングは確かGemini 2.5 Flashから始めたのかな~?
ですが、上手く行かずにGPT-5に移行したように思います。

ですが、GPT-5でも上手く行かずにGemini 2.5 Proに移行したこともありますが、
それでも上手く行かずに無料枠の範囲内で
Gemini 2.5 ProとGPT-5とGemini 2.5 Flashを行き来しながら可決できず、
VS CodeのGithub Copilotに移行しました。

これで解決できるか?と思っていましたが、
無料枠では限界が来て開発が出来なくなり・・・

ということで、
開発を止めることは出来なかったのでググったら
AnthropicのClaude Codeにたどり着きました。

Claude Codeは何やらコーディングが強いとか・・・

アプリを100日の間毎日つくる100日チャレンジをした
大塚あみ
さんも有料枠で使っているとか・・・

この記事を2週間の間に見た記憶はあったのですが、
改めて見ると・・・
2週間でここまで来たか・・・

Claude Codeに話を戻して、
コーディングが出来るAIと言えども適切な質問をしなければ
曖昧な答えしか得られないというのは当たり前。

そのことが広く認知されていれれば
プロンプトエンジニアリング
という言葉も出来てこなかったのではないでしょうか?

ということで、Claude Codeにログインして最初にいくつか質問されましたので
それに答えたらチャット履歴として下記が残っていました。
--------------------------------------------------
こんにちは、Claudeさん!一緒にコーディングしましょうをお願いできますでしょうか?追加情報が必要な場合は、重要な質問を1~2つお聞かせください。より良い結果のために必要な資料がございましたら、お申し付けください。Google Driveやウェブ検索など、利用可能なツールを必要に応じてご活用ください。分析ツールのご使用はお控えください。ご回答は親しみやすく簡潔な形でお願いいたします。

できるだけ早めにタスクを実行していただき、可能であれば成果物を作成していただけると助かります。成果物を作成する場合は、このタスクに最適な形式(インタラクティブ、ビジュアル、チェックリストなど)をご検討ください。ご協力ありがとうございます。
--------------------------------------------------
すると下記の回答が得られました。
--------------------------------------------------
こんにちは!コーディングのお手伝いをさせていただきます。
どのようなプログラムやアプリケーションを作りたいか教えていただけますか?例えば:

何を作りたいですか?

Webアプリ、ゲーム、計算ツール、データ可視化など


どの技術を使いますか?

JavaScript/HTML、React、Python、特定のライブラリなど



具体的なアイデアがあれば、すぐに実用的な成果物を作成いたします。アイデアが漠然としている場合でも、ご希望に合わせて提案させていただきます!
どのようなものを作ってみましょうか?
--------------------------------------------------
ということで、プロンプトエンジニアリングを行うことにしました。
その回答内容は
--------------------------------------------------
ネクストエンジンとGoogleスプレッドシートをAPI接続するGASを作成したいと思います。
スクリプトはQiitaなどへの公開を考えてコンテナバインドではなくスタンドアロンを考えています。
また、設定項目は上記同様にコード内に記載するのではなくスクリプトプロパティを使用したいと思います。
在庫数の取得が目的ですが、最初から行いたいこと全部となると、今までいくつかのAIといっしょに作業してきましたが認証で躓いていますので、まずは認証ができることを目標としたいと思います。
注意書きにつきましてはGASのトップでコメントとしてこのスクリプトの説明文を記載したいと思います。
ネクストエンジンAPIのエンドポイントは下記が参考になりますか?
https://developer.next-engine.com/api
ネクストエンジンのテスト環境設定についてスクリーンショットを貼り付けますので参考にしてください。
他に必要な情報はありますか?
--------------------------------------------------
・・・

これによりClaudeはネクストエンジンAPIの認証フローを確認してくれて、
認証フローを確認するために、公式ドキュメントを見てくれました。

--------------------------------------------------
理解しました!ネクストエンジンAPIの認証フローとスクリーンショットの情報を基に、認証に特化したGASスクリプトを作成します。
--------------------------------------------------

なんとも頼もしい回答なのですが、
他社のAIでも似たような回答がありましたので、
過度な期待はありませんでした。

ですが、何度かやり取りを行ったところ無事認証が取れました(^^♪

Claude Code スゲ~

因みに下記が途中まで上手く行った全文です。

--------------------------------------------------
/**
* ネクストエンジンAPI認証テスト用スクリプト
*
* 【目的】
* ネクストエンジンAPIとの認証を確立し、アクセストークンの取得を行う
*
* 【機能】
* 1. OAuth2認証フローの実行
* 2. アクセストークンとリフレッシュトークンの取得・保存
* 3. トークンの有効性確認
*
* 【設定方法】
* スクリプトプロパティに以下の値を設定してください:
* - CLIENT_ID: ネクストエンジンのクライアントID
* - CLIENT_SECRET: ネクストエンジンのクライアントシークレット
* - REDIRECT_URI: リダイレクトURI(スクリーンショット参照)
*
* 【注意事項】
* - テスト環境での動作確認を前提としています
* - 本番環境での使用前に十分なテストを行ってください
* - アクセストークンは安全に管理してください
*/

// ネクストエンジンAPIのエンドポイント
const NE_BASE_URL = 'https://base.next-engine.org';
const NE_API_URL = 'https://api.next-engine.org';

/**
* WebアプリとしてのGETリクエスト処理
* ネクストエンジンからのリダイレクト時にuidとstateを受け取る
*/
function doGet(e) {
const uid = e.parameter.uid;
const state = e.parameter.state;

if (uid && state) {
try {
// 自動的にアクセストークンを取得
const result = getAccessToken(uid, state);

return HtmlService.createHtmlOutput(`


ネクストエンジン認証完了




✅ 認証成功!


ネクストエンジンAPIの認証が完了しました。



取得した情報:



UID: ${uid}

State: ${state}

Access Token: ${result.access_token.substring(0, 20)}...

Refresh Token: ${result.refresh_token.substring(0, 20)}...


次のステップ:


GASエディタに戻り、testApiConnection() を実行してAPI接続をテストしてください。



このページを閉じて構いません。





`);

} catch (error) {
return HtmlService.createHtmlOutput(`


認証エラー



❌ 認証エラー


認証処理中にエラーが発生しました:


${error.message}


GASエディタでログを確認してください。




`);
}
} else {
return HtmlService.createHtmlOutput(`


パラメータエラー



❌ パラメータエラー


必要なパラメータ(uid、state)が見つかりません。


認証URLから正しくリダイレクトされていない可能性があります。


GASエディタで generateAuthUrl() を実行して、正しい認証URLを取得してください。




`);
}
}

/**
* スクリプトプロパティから設定値を取得
*/
function getScriptProperties() {
const properties = PropertiesService.getScriptProperties();

const clientId = properties.getProperty('CLIENT_ID');
const clientSecret = properties.getProperty('CLIENT_SECRET');
const redirectUri = properties.getProperty('REDIRECT_URI');

if (!clientId || !clientSecret || !redirectUri) {
throw new Error('必要なスクリプトプロパティが設定されていません。CLIENT_ID, CLIENT_SECRET, REDIRECT_URIを設定してください。');
}

return {
clientId,
clientSecret,
redirectUri
};
}

/**
* ステップ1: 認証URLを生成してログ出力
* 手動でブラウザでアクセスして認証を行う
*/
function generateAuthUrl() {
try {
const config = getScriptProperties();

// ネクストエンジンの認証URL
const authUrl = `${NE_BASE_URL}/users/sign_in?client_id=${config.clientId}&redirect_uri=${encodeURIComponent(config.redirectUri)}`;

console.log('=== ネクストエンジン認証URL ===');
console.log(authUrl);
console.log('');
console.log('上記URLをブラウザでアクセスしてください');
console.log('認証後、リダイレクトURLに uid と state パラメータが付与されて戻ってきます');
console.log('例: https://your-redirect-uri?uid=XXXXX&state=YYYYY');

return authUrl;

} catch (error) {
console.error('認証URL生成エラー:', error.message);
throw error;
}
}

/**
* ステップ2: uidとstateを使用してアクセストークンを取得
* @param {string} uid - 認証後に取得されるuid
* @param {string} state - 認証後に取得されるstate
*/
function getAccessToken(uid, state) {
try {
if (!uid || !state) {
throw new Error('uid と state が必要です');
}

const config = getScriptProperties();

// アクセストークン取得のリクエスト
const url = `${NE_API_URL}/api_neauth`;

const payload = {
'uid': uid,
'state': state,
'client_id': config.clientId,
'client_secret': config.clientSecret
};

const options = {
'method': 'POST',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
'payload': Object.keys(payload).map(key =>
encodeURIComponent(key) + '=' + encodeURIComponent(payload[key])
).join('&')
};

console.log('アクセストークン取得リクエスト送信中...');
console.log('使用URL:', url);
console.log('ペイロード:', payload);
const response = UrlFetchApp.fetch(url, options);
const responseText = response.getContentText();

console.log('レスポンス:', responseText);

if (response.getResponseCode() !== 200) {
throw new Error(`APIリクエストが失敗しました。ステータス: ${response.getResponseCode()}`);
}

const responseData = JSON.parse(responseText);

if (responseData.result === 'success') {
// トークンをスクリプトプロパティに保存
const properties = PropertiesService.getScriptProperties();
properties.setProperties({
'ACCESS_TOKEN': responseData.access_token,
'REFRESH_TOKEN': responseData.refresh_token,
'TOKEN_OBTAINED_AT': new Date().getTime().toString()
});

console.log('=== 認証成功 ===');
console.log('アクセストークン:', responseData.access_token);
console.log('リフレッシュトークン:', responseData.refresh_token);
console.log('トークンをスクリプトプロパティに保存しました');

return responseData;
} else {
throw new Error(`認証失敗: ${JSON.stringify(responseData)}`);
}

} catch (error) {
console.error('アクセストークン取得エラー:', error.message);
throw error;
}
}

/**
* ステップ3: 保存されたトークンでAPI接続をテスト
* ユーザー情報を取得して認証が正常に動作しているか確認
*/
function testApiConnection() {
try {
const properties = PropertiesService.getScriptProperties();
const accessToken = properties.getProperty('ACCESS_TOKEN');
const refreshToken = properties.getProperty('REFRESH_TOKEN');

if (!accessToken || !refreshToken) {
throw new Error('アクセストークンが見つかりません。先にgetAccessToken()を実行してください。');
}

// ログインユーザー情報取得APIでテスト
const url = `${NE_API_URL}/api_v1_login_user/info`;

const payload = {
'access_token': accessToken,
'refresh_token': refreshToken
};

const options = {
'method': 'POST',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
'payload': Object.keys(payload).map(key =>
encodeURIComponent(key) + '=' + encodeURIComponent(payload[key])
).join('&')
};

console.log('API接続テスト実行中...');
console.log('使用URL:', url);
console.log('ペイロード:', payload);

const response = UrlFetchApp.fetch(url, options);
const responseText = response.getContentText();

console.log('レスポンスコード:', response.getResponseCode());
console.log('API レスポンス:', responseText);

const responseData = JSON.parse(responseText);

if (responseData.result === 'success') {
console.log('=== API接続テスト成功 ===');
console.log('ユーザー情報:', responseData.data);

// トークンが更新された場合は保存
if (responseData.access_token && responseData.refresh_token) {
properties.setProperties({
'ACCESS_TOKEN': responseData.access_token,
'REFRESH_TOKEN': responseData.refresh_token,
'TOKEN_UPDATED_AT': new Date().getTime().toString()
});
console.log('トークンが更新されました');
}

return responseData.data;
} else {
throw new Error(`API接続テスト失敗: ${JSON.stringify(responseData)}`);
}

} catch (error) {
console.error('API接続テストエラー:', error.message);
throw error;
}
}

/**
* デバッグ用: 手動でuid/stateを入力してテスト
* 認証URLにアクセス後、リダイレクトURLのuid/stateを手動で入力
*/
function debugAuth() {
// ここにブラウザのリダイレクトURLから取得したuid/stateを入力してテスト
const uid = 'ここにuidを入力';
const state = 'ここにstateを入力';

if (uid === 'ここにuidを入力' || state === 'ここにstateを入力') {
console.log('uid と state を実際の値に変更してから実行してください');
return;
}

try {
const result = getAccessToken(uid, state);
console.log('デバッグテスト成功:', result);
} catch (error) {
console.error('デバッグテストエラー:', error.message);
}
}

/**
* 保存されているトークン情報を表示
*/
function showStoredTokens() {
const properties = PropertiesService.getScriptProperties();

console.log('=== 保存されているトークン情報 ===');
console.log('ACCESS_TOKEN:', properties.getProperty('ACCESS_TOKEN') || '未設定');
console.log('REFRESH_TOKEN:', properties.getProperty('REFRESH_TOKEN') || '未設定');
console.log('TOKEN_OBTAINED_AT:', properties.getProperty('TOKEN_OBTAINED_AT') || '未設定');
console.log('TOKEN_UPDATED_AT:', properties.getProperty('TOKEN_UPDATED_AT') || '未設定');
}

/**
* スクリプトプロパティをクリア(テスト用)
*/
function clearProperties() {
const properties = PropertiesService.getScriptProperties();
properties.deleteProperty('ACCESS_TOKEN');
properties.deleteProperty('REFRESH_TOKEN');
properties.deleteProperty('TOKEN_OBTAINED_AT');
properties.deleteProperty('TOKEN_UPDATED_AT');

console.log('トークン情報をクリアしました');
}

/**
* 認証フロー全体のガイド表示
*/
function showAuthGuide() {
console.log('=== ネクストエンジンAPI認証ガイド ===');
console.log('');
console.log('【事前準備】');
console.log('1. スクリプトプロパティに以下を設定:');
console.log(' - CLIENT_ID: あなたのクライアントID');
console.log(' - CLIENT_SECRET: あなたのクライアントシークレット');
console.log(' - REDIRECT_URI: リダイレクトURI');
console.log('');
console.log('2. スクリプトをWebアプリとしてデプロイ:');
console.log(' - 「デプロイ」→「新しいデプロイ」');
console.log(' - 種類: ウェブアプリ');
console.log(' - 実行者: 自分');
console.log(' - アクセス: 全員');
console.log(' - デプロイ後のURLをREDIRECT_URIに設定');
console.log('');
console.log('【認証手順】');
console.log('1. generateAuthUrl() を実行して認証URLを取得');
console.log('2. ブラウザで認証URLにアクセス');
console.log('3. ネクストエンジンにログイン');
console.log('4. 自動的にアクセストークンが取得されます');
console.log('5. testApiConnection() で動作確認');
console.log('');
console.log('【その他の関数】');
console.log('- showStoredTokens(): 保存済みトークン情報表示');
console.log('- clearProperties(): トークン情報クリア');
}
--------------------------------------------------

ネクストエンジン側で操作する点は色々ありますが、
Qiitaで記事をUpしたいと思います。

プロンプトエンジニアリングを行ったとは言え、
数度のやり取りでここまでのコーディングが出来る
Claude Code・・・やばい(-_-;)

みんカラユーザーには興味ない内容でしたね^^;
Posted at 2025/09/02 00:08:53 | コメント(0) | トラックバック(0) | 日記
2025年08月31日 イイね!

防草シート貼り

防草シート貼り今日も暑そうですが、昨日も暑かったですね(-_-;)

昨日も仕事だったそんな中、会社の敷地で土の部分に防草シート貼りを行っておりました。
土があると毎年草刈りするのが大変・・・(-_-;)

午前中は別の敷地で、建物の影になった部分で防草シート貼りを行っていて、
午後からはそんなに広くないこちらの場所を施工したのですが、
もっと日が陰ってからすればよかった(-_-;)

めちゃ汗だく^^;
Posted at 2025/09/01 08:38:15 | コメント(1) | トラックバック(0) | 日記
2025年08月30日 イイね!

新屋島水族館は改装中ですが・・・

新屋島水族館は改装中ですが・・・2025年4月6日(日)をもって今までの営業形態を終えて
2年間を目処にした改修工事に入りました。

それから5ヶ月弱が経過しておりまして、
建物は大部分が解体されています。

動物たちは何処いったん?と思いますが、
近くに市場水族館として出張しております。

でも、柵の向こうを見ると・・・
水槽の中にアザラシが居る(・・;)

どんな形態として生まれ変わるのかとても興味がありますよね~(^^♪

あと1年半強・・・

休日のルーティーンとして屋島に登りながら
新屋島水族館の工事の進み具合を見ていきたいと思います。
Posted at 2025/08/30 08:45:17 | コメント(0) | トラックバック(0) | 日記
2025年08月29日 イイね!

シーリングファンライトの改造

シーリングファンライトの改造以前、シーリングファンのある生活・・・というブログを上げましたが、
こちらの商品はかなりの難ありでした(-_-;)


こちらの部品がシーリングファンライトの重量と回転方向の剪断力の全てを受け止める部品がこちらになりまして、
こちらの強度が不足していることで動作不良になってしまいます。

ということで、ガラス繊維に二液性エポキシ樹脂を合わせて補強を行いました。

また、素材が不明でしたのがおそらくPP系ではなかろうかと思いまして、
TAMIYA 瞬間接着剤用プライマー
を施工前に塗布しました。

今回の施工でアキレスであったパーツの強度を確保出来たと思われますので、
長期間使用できることを期待しております^^;
Posted at 2025/08/29 21:16:32 | コメント(0) | トラックバック(0) | 日記
2025年08月28日 イイね!

休日のルーティーンは屋島登山

休日のルーティーンは屋島登山標高290m程の山を登山というのか?ハイキングというのか?
そういうのは置いといて(笑)

休日の朝のルーティーンは屋島に行くことから始まります。

酷暑の夏やけどイケるん?
とお思いの方もいらっしゃると思いますが、
タイトル画像の通り屋島の私が歩いているコースははまぁまぁな日陰があります。

Relive 'Morning Aug 26th'

Posted at 2025/08/28 20:09:54 | コメント(0) | トラックバック(0) | 日記

プロフィール

「ネクストエンジンとGoogleスプレッドシートをAPI接続できるGASの開発 http://cvw.jp/b/11052/48632484/
何シテル?   09/02 00:08
2025/06/23追記 ヘッダー画像について興味をお持ちの方もいらっしゃると思いますが、こちらは2025/06/21に香川県で開催されました、GAZOO 愛...
みんカラ新規会員登録

ユーザー内検索

<< 2025/9 >>

  123456
78910111213
14151617181920
21222324252627
282930    

リンク・クリップ

GAZOO 愛車広場 出張取材会 in 香川 満を持してチェイサーの記事が公開されました(^^) 
カテゴリ:その他(カテゴリ未設定)
2025/08/22 08:26:45
電費履歴リセット 
カテゴリ:その他(カテゴリ未設定)
2024/10/12 07:34:32
裏ワザでウィンドウズ11へ^^笑)。 
カテゴリ:その他(カテゴリ未設定)
2024/01/27 14:12:45

愛車一覧

トヨタ チェイサー GR Chaser TourerV TRD sports version (トヨタ チェイサー)
2025/06/21 GAZOO様の出張取材会で取材を頂きました。 https://ga ...
日産 リーフ 日産 リーフ
JZX100 Chaser 1JZ-GTE 2500cc ターボを所有しつつのセカンドカ ...
ホンダ アコード ホンダ アコード
私のではなく弟の車です。 色はアークティックブルーパールのEuro-Rです。 購入してし ...

過去のブログ

2025年
01月02月03月04月05月06月
07月08月09月10月11月12月
2024年
01月02月03月04月05月06月
07月08月09月10月11月12月
2023年
01月02月03月04月05月06月
07月08月09月10月11月12月
2022年
01月02月03月04月05月06月
07月08月09月10月11月12月
2021年
01月02月03月04月05月06月
07月08月09月10月11月12月
2020年
01月02月03月04月05月06月
07月08月09月10月11月12月
2019年
01月02月03月04月05月06月
07月08月09月10月11月12月
2018年
01月02月03月04月05月06月
07月08月09月10月11月12月
2017年
01月02月03月04月05月06月
07月08月09月10月11月12月
2016年
01月02月03月04月05月06月
07月08月09月10月11月12月
2015年
01月02月03月04月05月06月
07月08月09月10月11月12月
2014年
01月02月03月04月05月06月
07月08月09月10月11月12月
2013年
01月02月03月04月05月06月
07月08月09月10月11月12月
2012年
01月02月03月04月05月06月
07月08月09月10月11月12月
2011年
01月02月03月04月05月06月
07月08月09月10月11月12月
2010年
01月02月03月04月05月06月
07月08月09月10月11月12月
2007年
01月02月03月04月05月06月
07月08月09月10月11月12月
2006年
01月02月03月04月05月06月
07月08月09月10月11月12月
2005年
01月02月03月04月05月06月
07月08月09月10月11月12月
ヘルプ利用規約サイトマップ
© LY Corporation