GoogleBooksAPIおよびopneBDを利用した書籍情報の取得について

お世話になっております。

社内の図書管理用のアプリを作成しています。

レコード編集時に書籍情報をGoogleBooksAPIもしくはopneBDの片方から書籍情報を取得するスクリプトの作成まではできました。

実現したいこと:レコード編集時にGoogleBooksAPIに書籍情報を取得し、書籍情報がない場合opneBDから書籍情報を取得するというスクリプトを作成したいです。

プログラムは初心者というか、他サイトの情報を参考に作成したスクリプトで、コードの細かな部分まで完全に理解はできておりませんが、ぜひご教示のほどよろしくお願いいたします。

GoogleBooksAPIから書籍情報を取得するスクリプト

jQuery.noConflict();
(function($) {
"use strict";
/**
* レコード表示時にサムネイルを表示する
*/
kintone.events.on('app.record.detail.show', function(event) {
var record = event.record;
var output = kintone.app.record.getSpaceElement('thumbnail');
output.innerHTML = '<img src="' + record['サムネイル']['value'] + '">';

return event;
})

/**
* データ編集時に Google Books APIから書籍情報を取得
*/
kintone.events.on('app.record.edit.submit', function(event) {
var record = event.record;

return new kintone.Promise(function(resolve, reject) {
var isbn = record['ISBN']['value'];
kintone.proxy('https://www.googleapis.com/books/v1/volumes?q=' + isbn, 'GET', {}, {}, function(resp) {
resolve(resp);
}, function(resp) {
reject(resp);
});
}).then(function(resp) {
var data = JSON.parse(resp);
record['書籍タイトル']['value'] = data.items[0].volumeInfo.title;
record['書影']['value'] = data.items[0].volumeInfo.imageLinks.smallThumbnail;
record['書籍紹介ページ']['value'] = data.items[0].volumeInfo.infoLink;
record['著者']['value'] = data.items[0].volumeInfo.authors;
record['概要']['value'] = data.items[0].volumeInfo.description;
record['出版社']['value'] = data.items[0].volumeInfo.publisher;
      record['出版年月日']['value'] = data.items[0].volumeInfo.publishedDate;
      record['ページ数']['value'] = data.items[0].volumeInfo.pageCount;

return event;
}).catch(function(resp) {

openBDから書籍情報を取得するスクリプトです。

jQuery.noConflict();
(function($) {
"use strict";
/**
* レコード表示時にサムネイルを表示する
*/
kintone.events.on('app.record.detail.show', function(event) {
var record = event.record;
var output = kintone.app.record.getSpaceElement('thumbnail');
output.innerHTML = '<img src="' + record['書影']['value'] + '">';

return event;
})

/**
* データ編集時に openBD APIから書籍情報を取得
*/
kintone.events.on('app.record.edit.show', function(event) {
var record = event.record;

return new kintone.Promise(function(resolve, reject) {
var isbn = record['ISBN']['value'];
kintone.proxy('https://api.openbd.jp/v1/get?isbn=' + isbn, 'GET', {}, {}, function(resp) {
resolve(resp);
}, function(resp) {
reject(resp);
});
}).then(function(resp) {
var data = JSON.parse(resp);
record['書籍タイトル']['value'] = data[0].onix.DescriptiveDetail.TitleDetail.TitleElement.TitleText.content;
//record['サブタイトル']['value'] = data[0].onix.DescriptiveDetail.TitleDetail.TitleElement.Subtitle.content;
record['概要']['value'] = data[0].onix.CollateralDetail.TextContent[0].Text;
//record['著者']['value'] = ;
record['著者略歴']['value'] = data[0].onix.CollateralDetail.TextContent[2].Text;
//record['出版者']['value'] = ;
      //record['出版年月日']['value'] = ;
      //record['ページ数']['value'] = ;
      record['書籍紹介ページ']['value'] =data[0].summary.cover;
      record['書影']['value'] = data[0].onix.CollateralDetail.SupportingResource[0].ResourceVersion[0].ResourceLink;

return event;
}).catch(function(resp) {
// エラー発生時
event.error = '対象の書籍が見つからないか、APIエラーです' + resp;
return event;

});
});
})(jQuery);

QG.Kさん

お世話になっております。

「GoogleBooksAPIから書籍情報を取得するスクリプト」のthenのコールバック関数内で、data.items.length === 0 (書籍がない場合)とそうでない場合の条件分岐を行うと良いかと思います。(30行目あたり)

data.items.length === 0の場合はopenBDから書籍情報を取得を行い、そうでない場合は既存のdata.items[0]を用いてレコードを書き換える処理を続行すると良いかと思います。

江田篤史さん

お世話になっております。

条件分岐での処理とのことありがとうございます。

スクリプトの細かい部分把握できていないので、条件分岐についても色々調べながら試してみたいと思います。

また不明な点があればご質問させていただければと思います。

ありがとうございます。

関連して追加の質問になります。

Googlebooksに書籍データがない場合、openBDに書籍データを取得するのは江田様にてご指摘いただいたif,elseで解決できました。

Googlebooksの場合書籍データがない場合は下記条件で分岐できるのですが、

var data = JSON.parse(resp);
if(data.totalItems !== 0)

opneBDで書籍情報がない場合、[null]とだけ表示されます。

例)https://api.openbd.jp/v1/get?isbn=9784990495121

これをifで条件分岐する際にはどのように記述すればよろしいでしょうか?

QG.Kさん

もう解決されましたでしょうか。
少々気になって調べてみました。

配列にnullが入った状態で返ってきていますので

以下の条件分岐で如何でしょうか。

var data =JSON.parse(resp);
if(data !== null && data.totalItems !== 0 && data[0] !== null){

data自体がnullでないこと
dataの件数が0でないこと
dataの最初のデータがnullでないこと

書籍情報がない場合、必ず[null]が返るようであれば
省略して以下だけでも良いかもしれません。

var data =JSON.parse(resp);
if(data[0] !== null){

T.Hさん

お世話になっております。

ご指示いただいたスクリプトでデータがない場合の分岐はできそうです。

ありがとうございます。

if(data[0] !== null){

過去のコメントでif、elseの分岐できたとコメントしたのですが、実際にはただしく動作していませんでした。

elseの中をGoogleBooksAPIを参照するには、どのように記述すればよいかご教授いただけますでしょうか。

jQuery.noConflict();
(function($) {
"use strict";
/**
* レコード表示時にサムネイルを表示する
*/
kintone.events.on('app.record.detail.show', function(event) {
var record = event.record;
var output = kintone.app.record.getSpaceElement('thumbnail');
output.innerHTML = '<img src="' + record['書影']['value'] + '">';

return event;
})


/**
* データ編集時に openBD APIから書籍情報を取得
*/
kintone.events.on('app.record.edit.show', function(event) {
var record = event.record;

return new kintone.Promise(function(resolve, reject) {
var isbn = record['ISBN']['value'];
kintone.proxy('https://api.openbd.jp/v1/get?isbn=' + isbn, 'GET', {}, {}, function(resp) {
resolve(resp);
}, function(resp) {
reject(resp);
});
}).then(function(resp) {
var data = JSON.parse(resp);
if(data[0] !== null){
record['書籍タイトル']['value'] = data[0].onix.DescriptiveDetail.TitleDetail.TitleElement.TitleText.content;
}

      else{

}


return event;
}).catch(function(resp) {
// エラー発生時
event.error = '対象の書籍が見つからないか、APIエラーです' + resp;
return event;

});
});
})(jQuery);

 

 

 

だいぶざっくりですけどテストしてみました。
こんな感じで如何でしょうか?

jQuery.noConflict();
(function($) {
"use strict";

kintone.events.on('app.record.edit.submit', function(event) {
var record = event.record;

/**
* データ編集時に openBD APIから書籍情報を取得
*/
return new kintone.Promise(function(resolve, reject) {
var isbn = record['ISBN']['value'];
kintone.proxy('https://api.openbd.jp/v1/get?isbn=' + isbn, 'GET', {}, {}, function(resp) {
resolve(resp);
}, function(resp) {
reject(resp);
});
}).then(function(resp) {
var data = JSON.parse(resp);
if(data[0] !== null){
record['書籍タイトル']['value'] = data[0].onix.DescriptiveDetail.TitleDetail.TitleElement.TitleText.content;
//record['サブタイトル']['value'] = data[0].onix.DescriptiveDetail.TitleDetail.TitleElement.Subtitle.content;
record['概要']['value'] = data[0].onix.CollateralDetail.TextContent[0].Text;
//record['著者']['value'] = ;
record['著者略歴']['value'] = data[0].onix.CollateralDetail.TextContent[2].Text;
//record['出版者']['value'] = ;
//record['出版年月日']['value'] = ;
//record['ページ数']['value'] = ;
record['書籍紹介ページ']['value'] =data[0].summary.cover;
record['書影']['value'] = data[0].summary.cover;
}else{
record['書籍タイトル']['value'] = '' //ここで空を入れることで判定に使用
}
/**
* データ編集時に Google Books APIから書籍情報を取得
*/
return new kintone.Promise(function(resolve, reject) {
var isbn = record['ISBN']['value'];
kintone.proxy('https://www.googleapis.com/books/v1/volumes?q=' + isbn, 'GET', {}, {}, function(resp) {
resolve(resp);
}, function(resp) {
reject(resp);
});
});

}).then(function(resp) {
var data = JSON.parse(resp);
if(record['書籍タイトル']['value'] === ''){
if(data.totalItems !== 0){
record['書籍タイトル']['value'] = data.items[0].volumeInfo.title;
record['書籍紹介ページ']['value'] = data.items[0].volumeInfo.infoLink;
record['著者']['value'] = data.items[0].volumeInfo.authors;
record['概要']['value'] = data.items[0].volumeInfo.description;
record['出版社']['value'] = data.items[0].volumeInfo.publisher;
record['出版年月日']['value'] = data.items[0].volumeInfo.publishedDate;
record['ページ数']['value'] = data.items[0].volumeInfo.pageCount;
}else{
//データが無い時の処理
}
}
if(record['書影']['value'] === ''){
if(data.totalItems !== 0){
record['書影']['value'] = data.items[0].volumeInfo.imageLinks.smallThumbnail;
}
}

return event;

}).catch(function(resp) {
// エラー発生時
event.error = '対象の書籍が見つからないか、APIエラーです' + resp;

return event;

});
});
})(jQuery);

elseではrecordの書籍タイトルに空文字(‘’)を入れてみました。
1回目のthenでopenDBから値が設定されていれば、2回目のthenでは値を設定しないという構造です。
googleからの取得は必ず実行するロジックになっています。
もう少しうまい方法があるかもしれませんが、一応これで取得できることは確認しました。

追記:
最後、書影のところを別の if にしましたが、
項目ごとにopenDBにない場合にはgoogleから設定してもよいように思いました。

T.Hさん

スクリプトご提示いただきありがとうございます。

elseでのつなぎ方など勘違いしていた部分があり、勉強になりました。

ただ、こちらのアプリ環境では、何も情報を取得しない状態でした。

来週になってしまいますが、一つずつ確認してみたいと思います。

ありがとうございました。

QG.K さん

ざっくりテストなので、
タイトルと書影しか確認していませんでした。
(他の項目はコピーしただけです)
どうやら、データの中身が指定した場所に存在しないとcatchに行ってしまうようなので、
・データが存在するか
・データの中身の取り方があっているか
を分けて調査したほうがよさそうです。

追伸:
kintone.events.on に ‘app.record.create.submit’ を追加してみました。

jQuery.noConflict();
(function($) {
"use strict";
/**
* レコード表示時にサムネイルを表示する
*/
kintone.events.on('app.record.detail.show', function(event) {
var record = event.record;
var output = kintone.app.record.getSpaceElement('thumbnail');
output.innerHTML = '<img src="' + record['書影']['value'] + '">';

return event;
});

kintone.events.on(['app.record.create.submit','app.record.edit.submit'], function(event) {
var record = event.record;

/**
* データ編集時に openBD APIから書籍情報を取得
*/
return new kintone.Promise(function(resolve, reject) {
var isbn = record['ISBN']['value'];
kintone.proxy('https://api.openbd.jp/v1/get?isbn=' + isbn, 'GET', {}, {}, function(resp) {
resolve(resp);
}, function(resp) {
reject(resp);
});
}).then(function(resp) {
var data = JSON.parse(resp);
if(data[0] !== null){
record['書籍タイトル']['value'] = data[0].onix.DescriptiveDetail.TitleDetail.TitleElement.TitleText.content;
// record['サブタイトル']['value'] = data[0].onix.DescriptiveDetail.TitleDetail.TitleElement.Subtitle.content;
// record['概要']['value'] = data[0].onix.CollateralDetail.TextContent[0].Text;
record['著者']['value'] = data[0].onix.DescriptiveDetail.Contributor[0].PersonName.content;
// record['著者略歴']['value'] = data[0].onix.CollateralDetail.TextContent[2].Text;
// record['出版者']['value'] = ;
record['出版社']['value'] = data[0].onix.PublishingDetail.Imprint.ImprintName;
// record['出版年月日']['value'] = ;
// record['ページ数']['value'] = ;
// record['書籍紹介ページ']['value'] =data[0].summary.cover;
record['書影']['value'] = data[0].summary.cover;
var test=data[0];
console.log(test);
}else{
record['書籍タイトル']['value'] = '' //ここで空を入れることで判定に使用
}
/**
* データ編集時に Google Books APIから書籍情報を取得
*/
return new kintone.Promise(function(resolve, reject) {
var isbn = record['ISBN']['value'];
kintone.proxy('https://www.googleapis.com/books/v1/volumes?q=' + isbn, 'GET', {}, {}, function(resp) {
resolve(resp);
}, function(resp) {
reject(resp);
});
});

}).then(function(resp) {
var data = JSON.parse(resp);
if(data.totalItems !== 0){
console.log(data.items[0]);
}
if(record['書籍タイトル']['value'] === ''){
if(data.totalItems !== 0){
record['書籍タイトル']['value'] = data.items[0].volumeInfo.title;
// record['書籍紹介ページ']['value'] = data.items[0].volumeInfo.infoLink;
// record['著者']['value'] = data.items[0].volumeInfo.authors;
// record['概要']['value'] = data.items[0].volumeInfo.description;
// record['出版社']['value'] = data.items[0].volumeInfo.publisher;
// record['出版年月日']['value'] = data.items[0].volumeInfo.publishedDate;
// record['ページ数']['value'] = data.items[0].volumeInfo.pageCount;
}else{
//データが無い時の処理
window.alert("データがありません");
}
}
if(record['書影']['value'] === ''){
if(data.totalItems !== 0){
record['書影']['value'] = data.items[0].volumeInfo.imageLinks.smallThumbnail;
}
}

return event;

}).catch(function(resp) {
// エラー発生時
event.error = '対象の書籍が見つからないか、APIエラーです' + resp;

return event;

});
});
})(jQuery);

T.Hさん

お世話になっております。

動作できていない件、原因がわかりました。

いままで、レコード編集画面表示時(app.record.edit.show)にイベント発生させていたので、

T.Hさんのスクリプトも編集画面表示して、何も値を取得しないと勘違いしておりました。

T.Hさんのスクリプトではapp.record.edit.submitなのでレコード保存時に値を取得するようになっていたのですね。

ご提示いただいたスクリプトでこちらが意図する動きを確認できました。

(レコード編集時、レコード保存時どちらもOK)

 

これで社内運用開始できそうです。

ありがとうございました!

 

もう必要ないかもしれませんが、
自己研鑽の為にコードを見直しました。
よろしければご参考までに。

jQuery.noConflict();
(function($) {
"use strict";

/**
* レコード表示時にサムネイルを表示する
*/
kintone.events.on('app.record.detail.show', function(event) {
var record = event.record;
var output = kintone.app.record.getSpaceElement('thumbnail');
output.innerHTML = '<img src="' + record['書影']['value'] + '">';

return event;
});

kintone.events.on(['app.record.create.submit','app.record.edit.submit'], function(event) {
var record = event.record;

return new kintone.Promise(function(resolve, reject) {
var isbn = record['ISBN']['value'];
/**
* データ編集時に openBD APIから書籍情報を取得
*/
kintone.proxy('https://api.openbd.jp/v1/get?isbn=' + isbn, 'GET', {}, {}, function(resp) {
var data = JSON.parse(resp);
if(data[0] !== null){
record['書籍タイトル']['value'] = data[0].onix.DescriptiveDetail.TitleDetail.TitleElement.TitleText.content;
// record['サブタイトル']['value'] = data[0].onix.DescriptiveDetail.TitleDetail.TitleElement.Subtitle.content;
// record['概要']['value'] = data[0].onix.CollateralDetail.TextContent[0].Text;
record['著者']['value'] = data[0].onix.DescriptiveDetail.Contributor[0].PersonName.content;
// record['著者略歴']['value'] = data[0].onix.CollateralDetail.TextContent[2].Text;
// record['出版者']['value'] = ;
record['出版社']['value'] = data[0].onix.PublishingDetail.Imprint.ImprintName;
// record['出版年月日']['value'] = ;
// record['ページ数']['value'] = ;
// record['書籍紹介ページ']['value'] =data[0].summary.cover;
record['書影']['value'] = data[0].summary.cover;
}else{
record['書籍タイトル']['value'] = '';
record['著者']['value'] = '';
record['出版社']['value'] = '';
record['書影']['value'] = '';
}
resolve(event);
});
}).then(function(resp) {
return new kintone.Promise(function(resolve, reject) {
var isbn = record['ISBN']['value'];
/**
* データ編集時に Google Books APIから書籍情報を取得
*/
kintone.proxy('https://www.googleapis.com/books/v1/volumes?q=' + isbn, 'GET', {}, {}, function(resp) {
var data = JSON.parse(resp);
if(record['書籍タイトル']['value'] === ''){
if(data.totalItems !== 0){
record['書籍タイトル']['value'] = data.items[0].volumeInfo.title;
// record['書籍紹介ページ']['value'] = data.items[0].volumeInfo.infoLink;
record['著者']['value'] = data.items[0].volumeInfo.authors;
// record['概要']['value'] = data.items[0].volumeInfo.description;
record['出版社']['value'] = data.items[0].volumeInfo.publisher;
// record['出版年月日']['value'] = data.items[0].volumeInfo.publishedDate;
// record['ページ数']['value'] = data.items[0].volumeInfo.pageCount;
}else{
//データが無い時の処理
var warning="データがありません";
window.alert(warning);
console.log(warning);
}
}
if(record['書影']['value'] !== ''){
//openDBに書影あり
}else if(data.totalItems === 0){
//dataにitemsなし
}else if(!(data.items[0].volumeInfo)){
//items[0]にvolumeInfoなし
}else if(!(data.items[0].volumeInfo.imageLinks)){
//imageLinksなし
}else if(!(data.items[0].volumeInfo.imageLinks.smallThumbnail)){
//smallThumbnailなし
}else{
record['書影']['value'] = data.items[0].volumeInfo.imageLinks.smallThumbnail;
  }
// if(record['書影']['value'] === ''){
// if(data.totalItems !== 0){
// if(data.items[0].volumeInfo){
// if(data.items[0].volumeInfo.imageLinks){
// if(data.items[0].volumeInfo.imageLinks.smallThumbnail){
// record['書影']['value'] = data.items[0].volumeInfo.imageLinks.smallThumbnail;
// }
// }
// }
// }
resolve(event);
});
});
}).catch(function(resp) {
// エラー発生時
event.error = '対象の書籍が見つからないか、APIエラーです' + resp;
return event;

});
});
})(jQuery);

 

T.Hさん

お世話になっております。

修正したコードありがとうございます!

提示いただいたコードをベースに取得する項目の調整行っていきたいと思います。

 

 

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