2016年8月27日

再入荷お知らせメールの話2

再入荷お知らせメールの話の続き。

前回は、お客様が手軽にメール送信するだけの機能について、簡単に設置してみました。
メールを受けて→メモって→入荷メールを送信、と大部分を手動で運用する仕組みで、導入も簡単&知識もそれほど不要で、個人的にはおすすめです。

レンタルサーバーにデータベースを持つことで、手動で行っていた部分をPHPのプログラムに代行させることも可能です(前回と比べるとハードルが上がります)。
今回はそのあたりの説明と、コーディングについて書きます。

PHPとデータベース周りについては、この記事では解説していません。
ウェブアプリケーション構築においては、セキュリティ面も気を配る必要があります。
検索して調べるか書籍をあたって、慎重に検討してください。

動作テストは簡単にしか行っていません。
本番環境に実装する場合には、ご自身の責任でしっかりとテストを行ってください(ソフトウェアテストについて理解しておく必要があります)。


0. 仕様と留意点について


データベースにすでに登録されているという前提です(カラムは、id(連番)、pid(商品ID)、mail(お客様メール))。
登録フォームは、ご自分で用意ください。入力時の在庫ゼロチェック、登録のダブりチェック、登録メールアドレスのバリデーションなどをやっておく必要があります。


今回のコーディングは、カラーミーショップの更新をチェックし、データベース(MySQL)からデータを取得し、メール送信する部分です。

カラーミーショップAPIのみで「再入荷した商品」という判断をすることは、現状無理です。ドキュメントによると、都合よさそうなリクエストパラメータがありません。
仕方ないので、カラーミーショップAPIで、今日の更新データを取ってきて、在庫>0の商品IDを抽出しています。

この条件で「再入荷した商品」を抽出したというには、ちょっとまずいです。
たとえば、販売して在庫が5→4に減った場合、商品登録でコメントやその他項目などを更新した場合など、「再入荷したので在庫を増やした」以外の更新をたくさん含んでいます。
ただ、データベース登録時の在庫ゼロチェックがきちんされていれば、データベース検索時に「再入荷した商品」と無関係な商品は(たぶん)除外されます。


じゃぁそれでOKかというと、そうでもなくて。
サーバーに負荷をかけないためにも、明らかに不要な分は先に除外する方向で運用を決めたほうがよいと思います。
また、カラーミーショップAPIはリクエスト一回当たり最大50件なので、それより件数が多いと、複数回に分けてリクエストする必要があります(処理を追加する必要がありますし、リクエストも連投しすぎると制限がかかります)。
この点も考慮する必要が出てくるかもしれません。

お店の運用で再入荷商品であるとわかるような工夫して、条件に追加してやるのがベターだと思います(良い案もないので、ある程度の妥協は必要です)。
商品名につける、空き項目につける、再入荷カテゴリーに移動する、ここは手動にするなど。


今回のコーディングについての留意点。
「データベースに登録が0件だった場合は即終了」を追加すべきです(省略しています)。
エラー処理もろもろ、お客様にメール送信しましたよという報告メール、オプション在庫の対応、ヒットする件数が多い場合の追加処理、送信済みフラグを立てるのか、データベースから削除するタイミング、メール内容をきっちり作成、複数商品入荷した場合はメールをまとめる、メール送信規制の回避、などお店の事情で検討して、機能追加してください。


1. コーディング(人柱版)

<?php
//カラーミー
header("Content-Type:text/html; charset=UTF-8");//文字化け対策
$request_options = array(
    'http' => array(
        'method'  => 'GET',
        'header'=> "Authorization: Bearer xxxxxxxxxxxxxxx\r\n"
    )
);
$context = stream_context_create($request_options);
$url = 'https://api.shop-pro.jp/v1/products.json?limit=50&update_date_min=' . date('Y-m-d');
$response_body = file_get_contents($url, false, $context);
$response_json = json_decode($response_body, true);

//抽出、降順でソートしておくと処理が減らせる
for($i=0; $i<count($response_json['products']); $i++){
    if($response_json['products'][$i]['stocks'] > 0) $data[] = $response_json['products'][$i]['id'];
}

//データベース
$dsn = 'mysql:dbname=mydb;host=hostname';
$user = 'username';
$password = 'password';

try{
    $pdo = new PDO($dsn, $user, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    for($i=0; $i<count($data); $i++){
        $sql = 'SELECT DISTINCT mail FROM restock WHERE pid=?';
        $stmt = $pdo->prepare($sql);
        $stmt->execute(array($data[$i]));
        foreach ($stmt as $row) {
            //メール送信
            mb_language("Japanese");
            mb_internal_encoding("UTF-8");
            $to = $row['mail'];
            $subject = 'SUBJECT';
            $message = $data[$i];
            $headers = 'From: shop@example.co.jp' . "\r\n". 'Return-Path: shop@example.co.jp';
            $send_mail=mb_send_mail($to, $subject, $message, $headers);

            if ($send_mail) {
                $sql = 'DELETE FROM restock WHERE pid=? AND mail=?';
                $stmt = $pdo->prepare($sql);
                $stmt->execute(array($data[$i], $row['mail']));
            } else {
                //エラー処理
            }
        }
    }
} catch (PDOException $e){
    //print('Error:'.$e->getMessage());
    die();
}


2. おわりに 


このあたりで、作業の半分くらいだと思います。
私は試しに作っただけで、実装する予定はありません。 のこり半分を自分で仕上げられる人用です
バグ報告していただけると、私が喜びます。

ソフトウェアテストも、コーディングと同様に大事な技術になります。
十分なインプットが必要です。

cronで自動実行する予定です(レンタルサーバー次第)。

XAMPPを使ってメール送信のテストをする場合は、事前に設定が必要です。
検索して調べてください。

再入荷お知らせメールの話3」につづきます。

[追記]
PHPやPHPセキュリティの入門書によると、(フォーム入力時に当然バリデーションしてから登録するのですが)データベースの登録内容も無条件に信用せずに、データをあらためてバリデーションするくらいの丁寧な仕事が必要だそうだ(カラーミーショップAPIも含む)。
pid、mail、その他データベースからの項目もチェックする姿勢で臨むほうがよいと考えます。

2016年8月21日

再入荷お知らせメールの話

カラーミーいじりたおしの記事数が95(100目前!)になりました。
純粋に”それ”が好きってだけでここまで来ましたが、好きを超えるモチベーションというものも、なかなか見つからないものです。私は、わりと幸せだなぁと感じます。
カラーミーショップでお店をされている方でも、似たような想いで、仕事をされてる方も多いのではないでしょうか。


さて、本日の話題はこれ。
「再入荷お知らせ」「入荷連絡メール」「再入荷連絡メール」「再販売お知らせメール」、カートによって色々な呼び方があります、あれです。
 
カラーミーショップにはなぜかついていない「再入荷お知らせメール」機能、カラーミー七不思議のひとつ。
「この商品について問い合わせる」リンクがありますので、それを代用していらっしゃるお店もあるかと思います。
そのほかには、オプションボタン、チェックボックスを設置するために、新しく問い合わせフォームを作って、レンタルサーバーに置いているお店もあります。

カラーミーショップ的にどんなことができるでしょうか。機能設置について、検討してみました。
先に書きますが、今回のはあまり役に立たないコードになっています。


0. 一般的な「再入荷お知らせ」機能の流れ


登録部分
  1. 商品詳細ページのリンクをクリックする
  2. 入力フォームが開く
  3. メールアドレスを入力する
  4. OKボタンで、登録完了メールを送信
  5. データベースに追加

入荷連絡部分
  1. 在庫0から増加したら、メール送信


いくつかのカートを見てみましたが、傾向としては、
  • 登録はできるが、削除する方法は実装されていない
  • アカウントと紐づいていない(誰でも登録できる)
  • 在庫チェック・メール送信は一定時間毎


処理で一番考える必要があるのは入荷連絡部分。
仕様を細かく決めて、例外を丁寧に作りこむ必要もあります。
自前でデータベースを持つと、バックアップなどのサーバー運用と、サーバー障害時の対応も考えておく必要があります。

以上を踏まえて、楽に作れる範囲まででコードを書いてみました。
登録数が少なければ、これくらいでもいいかなと思います。
今回の仕様説明は、コードの次に書いてあります。


1. コード


商品詳細ページ
<form action="http://php.example.jp/sendMail.php" method="POST" name="form1">
  <input type="hidden" name="pid" value=<{$product.id}>>
  <input type="hidden" name="id" value=<{$members_id}>>
  <a href="#" onClick="document.form1.submit();">入荷したら連絡</a>
</form>    

sendMail.php
<?php
$request_options = array(
    'http' => array(
        'method'  => 'GET',
        'header'  => "Authorization: Bearer XXXXXXXXXX\r\n"
    )
);
$context = stream_context_create($request_options);

$url = 'https://api.shop-pro.jp/v1/customers/' . $_POST['id'] . '.json';
$response_body = file_get_contents($url, false, $context);
$response_json = json_decode($response_body, true);

$url2 = 'https://api.shop-pro.jp/v1/products/' . $_POST['pid'] . '.json';
$response_body2 = file_get_contents($url2, false, $context);
$response_json2 = json_decode($response_body2, true);

mb_language("Japanese");
mb_internal_encoding("UTF-8");

$to = 'info@example.jp';
$subject = $response_json['customer']['name'] . ' 様から再入荷登録';
$message = $_POST['pid'] . ', '. $response_json2['product']['name'] . ', ' . $response_json['customer']['mail'];
$headers = 'From: info@example.jp' . "\r\n";

mb_send_mail($to, $subject, $message, $headers);
header(sprintf("Location: http://example.jp/?pid=%s", urlencode($_POST['pid'])));
exit();


2. 妙な仕様


カラーミーAPI実践編2 ポイント表示」をベースに、妙な仕様にしています(楽&長くならない範囲にするため)。省いたところは、ご自身で調べてください。

クリックしたら即メールで、パラメータのバリデーション、ログインのチェック、「登録しました」の表示や、お客様に登録完了メールを送らないのも、作りとしてはかなり省略しています。
コピペしたらすぐに使えるような仕様にはなっていません。改造・自習用にどうぞ。
ブログの都合上、改行不要なところに改行が入っていますので、注意してください。

仕様は、クリックすると、商品IDと会員IDをPHPに送って、カラーミーショップAPIで必要項目をとってきます。
上例では、商品ID、商品名、会員登録しているメールアドレスを、お店にメール送信するようになっています(ログインしていないとメールアドレスは空です)。
$toがお店宛。
お店メールで受けて、お店でメモするなり管理します。

商品詳細ページから必要な情報をすべて送れるなら、カラーミーショップAPIは不要(本当に必要な情報は、商品名とメールアドレスくらい)。


ログイン限定にするなら、会員の名前も送って、会員IDと名前をカラーミーショップAPIでチェックすれば、いたずら避けになるかと思います。


ログイン不要にするなら、メール登録の入力フォームを開くときにサーバーからトークンを送ってもらうかたちにします。検索するとトークン生成の方法が見つかります。
クリックするとPHPを呼び出し、PHPで入力フォームを作って、そこでメールアドレスを入力してもらうようにします。
他人のメールアドレスを勝手に登録されるようないたずらは除外できません。


上例には例外処理を書いていません。
例えば、送られてきた会員ID・商品IDが該当しない場合(これはありえます)。カラーミーショップAPIでエラーになるので、その場合の処理が必要です。


3. おわりに


データベースに登録~在庫チェック~メール送信までの流れも検討しましたので、まとまった時間のあるときにでも、試してみようかと思います。 

とはいえ、自分自身で調べられる方でないと、実際に運用していくことは難しいかもと思います。

再入荷お知らせメールの話2へ続く。

[参考]
IPA - 安全なウェブサイトの作り方
セキュリティ上の問題となる箇所と対応について記載されています。ウェブアプリケーション構築において重要な話題ですので、ご一読を。

2016年8月8日

参考にしたいカラーミーショップ 7

カラーミーショップ大賞2016」 のノミネート一覧が発表(約840店舗)されてから随分経ってしまいましたが、今年もわりと丁寧にチェックしてきました(遅ればせながら)。

今年のノミネートショップから気づいた点は、
レスポンシブが増えてきている
お知らせ欄があまり使われなくなった
CSS3のアニメーション効果が増加
www.をつけないURLが増えた
画像にPinterestのボタンがやや増えてきた
グローバルナビゲーションが減ってきてるかも
3カラムが減ったかも

比較的新しい機能も実装されてたりで、いずれも時代の移り変わりのような流れを感じます。游ゴシック、游明朝をみかけるようになって、プッシュ通知がついていたところもありました。

トップページをカラーミー以外で作っているサイトも多く、カラーミーショップのカート部分だけをどこでもカラーミーでつけていることも多かったです。
サイト構成を凝った感じにできますし、一見するとネットショップらしくないデザインにできるので、おっという感じになります。

見て楽しそうなのを選びましたので、お楽しみください。


1カラム


カメラケース・カメラバッグ通販の静岡日和ストア

商品数が少ない場合には1カラム。広く使えるので、お店のイメージを全面に押し立てる感じに。
トップページを綺麗に作ってありますし、他ページも細部まで丁寧。




鳥さんのオリジナルグッズ・鳥柄雑貨 BIRDSTORY SHOP

愛らしさが存分に伝わる、広々としたトップページ。
トップページ以外は2カラムで、サイドバーに機能を配置。うぉって感じです。





2カラム


パンと日用品の店 わざわざ

ヘッダーに大きいスライダー。かなり印象的。
大部分がカラーミー以外なので、デザインの自由度もかなり高め。




光浦醸造|公式ホームページ・オンラインショップ|

3カラムっぽい2カラム。カラーミー以外の部分もあって、複雑な構造。
フォント(游ゴシック体)の雰囲気が合っています。





3カラム


新潟Tシャツ委員会

ショップサイトなのに、別もののコンセプトを感じます。
商品詳細ページにFacebook Comments Pluginでコメント欄を設置(他ショップでもまれにあり)。




のぼり旗の反応率がダントツ!【デザインのぼりショップ】

3カラムらしい、詰まった感じが好きです。
共通部分にバナーをいっぱい貼りたい場合はやっぱり3カラム必要。




おわりに


レスポンシブの有料テンプレートをベースにしているサイトも、結構多かったように思います。

CSS3のセレクタとCSSの画像置き換えを使って、カート画面(SSLページ)の画像を差し替えているお店がありました(いま現在、カラーミーショップの店舗は閉店されていました)。これはちょっと使えるなと。いつかご紹介させていただきます。

去年の記事「参考にしたいカラーミーショップ 1~6」も、結構面白いので、ぜひどうぞ。