« DELL Inspiron 5485 開封の儀(物理) | トップページ | Vue.jsのプロジェクトをSpringに突っ込む »

2020年10月10日 (土)

Webショップ運営を(ほぼ)自動化した件

0. 弊社、Web販売もやってます

弊社はYahoo!ショッピングに出店しているんだが、問屋とのやり取り含め、その運営がまるごと手作業で結構手間だったりする。

一部の問屋は発送の代行もしてくれる、いわゆるドロップシッピング業者なのだが、そこを使った場合でも大まかな流れはこんな感じ。

1

人が監視する手前、受注はYahoo!ショッピングから送られてくるメールがトリガーになるので、担当者が不在の場合はどうしても遅れが生じるし、問屋への発注締め切り時刻を超過してしまうとその分エンドユーザーへの発送も遅延する。というのが悩みの種だった。

1. なので自動化に挑んだ

幸いYahoo!ショッピングにはストア運営を自動化するためのAPIが用意されているので、これを利用して受発注と発送通知の自動化に挑んだ。

で、こんな感じに。

2

1-1. 受注をfetchして発送依頼データを作るまで

件のストア運営を自動化するためのAPIを使ってストア運営する流れについては、公式の注文APIガイドに沿って順番にAPIコールしていけばいいので、これ自体は特に難しいことはなかった。
ただ、ここのAPIはXMLを投げ合う類だったりする。

肝心のシステムにはSpring Batchを使った。言語はJava。理由は単純、自分がJavaに比較的慣れていたためだ。

幸いJavaにはJava Architecture for XML Binding(JAXB)という公式の自動マッピング仕様があるため、XMLによるリクエスト/レスポンスデータとオブジェクトとの相互変換には、これを使うことで比較的容易に対応できた。
とはいえ、最初は「XMLかよ~」と泣きながらJAXBの解説記事を漁っていたのだが(あせ

で、取得した受注データから、発送依頼用ファイルを作るわけだが、相手方がシフトJISなCSVでのみ受け付けるため、色々見て回った結果opencsvを使うことにした。オブジェクトからCSVを生成するだけなので、特段苦労はなかった。

1-2. 発送依頼データをアップロードする

相手方の卸業者は受注や発送状況に関するAPIを持っていないとの話(こればっかりは仕方ない)なんだが、先方に確認したところ先方に確認したところ幸いにもRPA等の機械的なアクセスまでは禁じているわけではなかったので、Seleniumによるオートパイロットで発送依頼処理を代行させることにした。

こちらも最初はすべてSpring Batchで書いていたんだが、以下のような問題が出てきたのでSpringで書くのをやめ、処理を分離することにした。

  • WebDriverをSpringでBeanにしている場合、個々のオートパイロット処理の終了時にWebDriverをクローズすると、その「クローズされた状態」を次の処理で使いまわすため、WebDriverが開始できなくて倒れる
    まぁ、Seleniumはもともとテストツールで、JUnitなんかと一緒に動かすことが前提のものであって、インスタンスが使いまわされるような使用法は想定していないんだろう
  • AWSに受発注処理用サーバを置いて動かしていたら、相手方から攻撃とみなされてしまったらしく、IPベースで接続を遮断されてしまったため、AWS上に置けなくなってしまった
    「パブリックIP変えればええやん」とお思いになるかと思うが、Yahoo!ショッピングの本番系にAPIアクセスするには固定のパブリックPが必要で、これを変えるにはまた申請が必要だったりするので面倒

後半のやつについては「やりすぎました、ほんとごめんなさい」というだけの話で、先方にも当然のことながら謝りを入れた。けれども、一度遮断したIPアドレスを開けてくれるわけもなく、引っ越しを余儀なくされることに。

どういうわけか弊社には、社内システム用のプライベートクラウド的な仮想化基盤があり、まだ余裕がありそうだったのでそこに発送依頼データのアップロードを行うVMインスタンスを作ることにした。

引っ越し先は決まったとして、Spring Batchで書いていた処理だけを切り出してやるのではなく、せっかくなのでGoで一から書いてみることにした。
要件的にDBアクセスが必要な個所はなかったことと、幸いにもほぼSeleniumなagoutiという受け入れテスト用ライブラリがあったので、agoutiでオートパイロットする処理を実装。AWS側で発送依頼データのCSVを作ったらscpでアップロード用VMに送り込み、頃合いを見計らってGoで作ったオートパイロット処理でファイルをアップロードする、という算段だ。

1-3. 発送状況の追跡と更新

こちらは、前述とは逆の流れ。
先方からは発送状況をCSVでダウンロードできるので、Goで作った「発送状況CSVをダウンロードする処理」でCSVをダウンロードし、こいつをscpでAWS上の受発注処理用サーバに送り込んで、Spring BatchでCSVのパースと発送ステータスの変更を行う、という流れになる。

この段階でも、CSVがシフトJISという以外は特段苦労なくパースできた。

Yahoo!ショッピングのAPIで該当の注文に対してパース結果の運送業者と配送伝票番号を埋めたあと、Springのメール送信機能で注文者に発送状況を通知している。本文については、Thymeleafのテキストテンプレート機能を使った。

Springのメール送信機能については、Guide to Spring Emailという記事が大いに参考になった。

2. で、どうなったか

ひとまず、Webでの受発注はひととおり自動化したのだが、そうもいかない場合も存在する。例えばこんな感じ。

  • 「領収書の要否をカートに表示する」設定にしていて、注文ボタンが出ている画面に「領収書をどうするか」という選択が出ているのに、領収書不要でお客様要望欄に「領収書をください」と書いている場合がある
  • 同じく、領収書必要にはなっているが、お客様要望欄に宛名や但書に関する指定がある
  • 期日指定配送は承っていないのだが、お客様要望欄に「○○月××日必着で願います」と書かれている場合がある

こういう場合はどうしても人による確認が必要になるので、どんな対応が必要なのかを社内のMLに流す処理を追加することで対応した。一応、人間様は結果だけ受け取るという状況にはできたといえるが、今後は

  • 領収書の自動作成(※額面5万円以上の場合は印紙が必要になるのでテンプレートはそこで分ける必要があるが)
  • 受注結果をチャットのタイムラインに流す

あたりをやっていきたいと思う。

« DELL Inspiron 5485 開封の儀(物理) | トップページ | Vue.jsのプロジェクトをSpringに突っ込む »

コメント

コメントを書く

(ウェブ上には掲載しません)

« DELL Inspiron 5485 開封の儀(物理) | トップページ | Vue.jsのプロジェクトをSpringに突っ込む »

2023年12月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            

最近のトラックバック

無料ブログはココログ