スマホのカメラで中古本せどりができるようになった話
中古本せどりをしたい、けど初期費用は抑えたい。
そんな人に向けてこの記事を書きます。
このnoteを読めば、今日から中古本せどりができる環境が出来上がります。
もちろん、初期費用を抑えているため、本格的なツールや、本せどり専用の機械を持っている人には勝てません。
それでも「いきなり初期投資をして失敗するのは嫌だ。」と思うのは自然なことです。そんな人に向けてなるべく低コストで環境を作れるようにしたくて記事を書きました。
低コストの肝は「スプレッドシート」
環境を作るためにスプレッドシートのマクロを組んで、ツールを作ります。
その自作ツールを使い、バーコードをスキャンすると
本の表紙
本の著者やタイトル
Amazonの中古価格
keepaの中古価格推移グラフ
メルカリURL
などが表示され、せどりをする上で最低限必要な情報が出力されます。
スプレッドシートのマクロを組むので、最低限の知識は必要です。
しかし、コードを丸々置いておくのでコピペすればできますし、(今後有料予定の)コピーするだけで使えるようにするので、面倒な人はを参照ください。
用意する物
ネット環境につながったスマホ
スプレッドシート
PC
スプレッドシートのマクロ(Google Apps Script)を書く
早速ですが、マクロの中身を書きます。
新規プロジェクトを作り「コード.gs」として以下を記載してください。
const BOOK_API_PREFIX = 'https://www.googleapis.com/books/v1/volumes?country=JP&q=isbn:';
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
function dispInputISBNCode() {
//入力するメッセージボックス
var result = Browser.inputBox("ISBNを記入してください", "ISBN:", Browser.Buttons.OK_CANCEL);
if (result != "cancel"){
addBook(result);
}
}
function addBook(isbnCode) {
try {
const bookInfo = _fetchBookInfo(isbnCode);
_appendBookRow(bookInfo);
} catch (error) {
console.error(error);
}
}
function _fetchBookInfo(isbnCode) {
const searchRes = UrlFetchApp.fetch(BOOK_API_PREFIX + isbnCode);
const searchResJSON = JSON.parse(searchRes.getContentText());
if (!searchResJSON.hasOwnProperty('items')) {
Browser.msgBox(書籍が見つかりません);
}
const bookInfoRes = UrlFetchApp.fetch(searchResJSON.items[0].selfLink + '?country=JP');
return JSON.parse(bookInfoRes.getContentText());
}
function _appendBookRow({volumeInfo}) {
const title = volumeInfo.title;
const authors = volumeInfo.authors?.join(',') ?? '';
const isbnCode = volumeInfo.industryIdentifiers.find(v => v.type === 'ISBN_13').identifier;
const thumbUrl = volumeInfo.imageLinks?.smallThumbnail;
const thumb = thumbUrl ? `=IMAGE("${thumbUrl}")` : null;
const sheet = SpreadsheetApp.getActiveSheet();
var lastrow = parseInt(sheet.getLastRow()) + 1;
const merkari = "=\"https://jp.mercari.com/search?keyword=\"&B" + lastrow + "&\"&status=on_sale\"";
const asin0 = "";
const asin1 = "=MOD(ABS(D" + lastrow + " ),10)";
const asin2 = "=LEFT(D" + lastrow + " ,3)";
const asin3 = "=MOD((MID(D" + lastrow + " ,4,1)*10)+(MID(D" + lastrow + " ,5,1)*9)+(MID(D" + lastrow + " ,6,1)*8)+(MID(D" + lastrow + " ,7,1)*7)+(MID(D" + lastrow + " ,8,1)*6)+(MID(D" + lastrow + " ,9,1)*5)+(MID(D" + lastrow + " ,10,1)*4)+(MID(D" + lastrow + " ,11,1)*3)+(MID(D" + lastrow + " ,12,1)*2),11)";
const asin4 = "=IF(I" + lastrow + "=11,0,IF(I" + lastrow + "=10,\"X\",11-I" + lastrow + "))";
const asin = "=MID(D" + lastrow + " ,4,1)&MID(D" + lastrow + " ,5,1)&MID(D" + lastrow + " ,6,1)&MID(D" + lastrow + " ,7,1)&MID(D" + lastrow + " ,8,1)&MID(D" + lastrow + " ,9,1)&MID(D" + lastrow + " ,10,1)&MID(D" + lastrow + " ,11,1)&MID(D" + lastrow + " ,12,1)&J" + lastrow;
const amazonURL = "=\"https://www.amazon.co.jp/dp/\"&K" + lastrow;
const blank =""
const amazonUsedPrice = "=IMPORTXML(L" + lastrow + ",\"//*[@id='tmmSwatches']/ul/li/span/span[3]/span[1]/span/a/text()[1]\")";
sheet.appendRow([thumb, title, authors, isbnCode, merkari, asin0, asin1, asin2, asin3, asin4, asin, amazonURL, blank, blank, amazonUsedPrice]);
//サムネ用高さ調整
if (thumb) {
const row = sheet.getLastRow();
sheet.setRowHeight(row, 90);
}
}
次にコード.gsと同じ階層に「index.html」を作成し、下記を記載してください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/quagga/0.12.1/quagga.min.js" integrity="sha512-bCsBoYoW6zE0aja5xcIyoCDPfT27+cGr7AOCqelttLVRGay6EKGQbR6wm6SUcUGOMGXJpj+jrIpMS6i80+kZPw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<style>
body, html {
margin: 0;
overflow: hidden;
}
#camera -view {
width: 100%;
height: auto;
}
</style>
</head>
<body>
<div id="camera-view"></div>
<script>
Quagga.init({
locate: false,
frequency: 2,
inputStream: {
type: 'LiveStream',
target: document.getElementById('camera-view'),
constraints: {
width: 1080,
height: 1080,
frameRate: 10,
tryVertical: true,
facingMode: 'environment',
focusMode: 'continuous',
successTimeout: 1000,
},
area: {
top: '20%',
right: '20%',
left: '20%',
bottom: '20%',
},
},
decoder: {
readers: ['ean_reader'],
multiple: false,
},
}, error => {
if (error) {
console.error(error);
return;
}
Quagga.start();
});
Quagga.onDetected(async result => {
if (!confirm(result.codeResult.code + ' : コードを登録しますか?')) {
return;
}
google.script.run.addBook(result.codeResult.code);
});
</script>
</body>
</html>
シート側の記載
「M1」に以下の関数を記入してください。
これはkeepaからランキング波形グラフをとってくるための記載です。
=ArrayFormula(ifs(ROW(K:K)=1,"",K1:K="","",true,IMAGE("https://graph.keepa.com/pricehistory.png?yzoom=0&amazon=0&new=0&domain=5&range=365&salesrank=1&asin="&K1:K, 4, 70, 175)))
続いて隣のセルの「N1」に以下の関数を記入してください。
こちらは中古価格推移の波形となります。
=ArrayFormula(ifs(ROW(K:K)=1,"",K1:K="","",true,IMAGE("https://graph.keepa.com/pricehistory.png?yzoom=1&amazon=0&new=0&used=1&domain=5&range=365&salesrank=0&asin="&K1:K, 4, 90, 175)))
以上です。参考は以下のサイトとなります。
あとは、「デプロイ」→「新しいデプロイ」でデプロイすることで、URLが発行されるので、そのURLをスマホで開くとカメラが起動した状態のwebサイトが出てきます。
そのカメラでバーコードを読み取ると、登録確認画面が出てきて、「OK」を押すことでスプレッドシートに本の情報が出力されます。
シートの調整
素のままのシートだとASIN出力の際に使用したセルが丸見えだと思いますので、適宜F列~J列の幅を0にして見えないようにすることをお勧めします。
1列目はMとN列以外は何を書いてもいいです。
また、コード.gsに書いた「dispInputISBNCode」関数はカメラから読み取る際には使わない関数で、直接ISBNコードを入力する用です。
シートにボタンを作り、関数を呼ぶようにすることで、スマホがなくても情報を出力できるようになります。
最後に
こちらのGAS、シートの内容ともに未完成です。
ただ、自分でツールを改造できるので、ここからどんどん欲しい情報が出せるように付け足したり、電脳せどりに使えるようにしたりすることができます。
ぜひ、その土台として、ご活用ください!
不具合
現状確認している不具合としては、最終行に追加するメソッドがうまくいかず、1000行追加されたり、突然6万行下(一番下の行)のセルに入力されたりします。
調査中ですがわかり次第、追記または新しいnoteにて報告します。
この記事が気に入ったらサポートをしてみませんか?