🛒 買い物支援マッチングシステム
買い物難民とサポーターをつなぐ地域共助プラットフォーム
• 連絡先: 電話番号も記載すると安心
• お礼: 地域通貨や現金で感謝の気持ちを
サポーター登録
登録済みサポーター
• 連絡はこまめに: 買い物前後に状況を伝える
• レシートは必ず: 金額の透明性を保つ
• 謝礼は受け取ってOK: 地域通貨や少額のお礼
買い物支援システム構築の完全ガイド
地域で実際に運用できるシステムの作り方
まずは問題の本質を理解する
- 買い物難民の実態: 高齢化率38%の安来市では、免許返納後の移動手段がない人が増加
- 既存の課題: 民間配達サービスは都市部のみ、移動販売車も週1-2回程度
- このシステムの強み: 既存の「買い物に行く人」を活用した相互扶助モデル
- ターゲットユーザー: 依頼者(70歳以上)とサポーター(30-60代の地域住民)
💡 成功の鍵: ITシステムだけでなく、地域コミュニティとの連携が不可欠。社協、民生委員、町内会との協力体制を構築しましょう。
実装しやすく、運用しやすい技術を選ぶ
- なぜシンプルな構成?: 地方では複雑なシステムの保守が困難。メンテナンスしやすさを最優先
- LINE連携は必須: 高齢者のスマホ普及率は低いが、LINEは使える人が多い
- WordPress統合: 既存の市のサイトがWordPressなら、カスタムHTMLで埋め込み可能
- スケーラビリティ: 最初は1地区100人規模、将来は市全体3万人に拡大可能な設計
💡 コスト重視なら: Herokuの無料プラン廃止後は、Railway(月5ドル〜)やRender(無料プランあり)がおすすめ。
必要最小限のテーブル構成
- usersテーブル: 依頼者・サポーター共通(user_id, name, location, phone, line_id, role)
- requestsテーブル: 買い物依頼(request_id, user_id, shop_name, items, preferred_date, status)
- matchesテーブル: マッチング記録(match_id, request_id, helper_id, matched_at, completed_at)
- reviewsテーブル: 評価(review_id, match_id, rating, comment)
CREATE TABLE users ( user_id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, location VARCHAR(200), phone VARCHAR(20), line_id VARCHAR(100), role VARCHAR(20), -- 'requester' or 'helper' created_at TIMESTAMP DEFAULT NOW() ); CREATE TABLE requests ( request_id SERIAL PRIMARY KEY, user_id INT REFERENCES users(user_id), shop_name VARCHAR(200), items TEXT, preferred_date VARCHAR(100), status VARCHAR(20) DEFAULT 'waiting', -- 'waiting', 'matched', 'completed' created_at TIMESTAMP DEFAULT NOW() ); CREATE TABLE matches ( match_id SERIAL PRIMARY KEY, request_id INT REFERENCES requests(request_id), helper_id INT REFERENCES users(user_id), matched_at TIMESTAMP DEFAULT NOW(), completed_at TIMESTAMP );
💡 個人情報保護: 電話番号やLINE IDは暗号化して保存。GDPR/個人情報保護法に準拠したプライバシーポリシーを必ず用意。
Node.js + Expressでシンプルなサーバー構築
const express = require('express');
const { Pool } = require('pg');
const app = express();
// データベース接続
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false }
});
app.use(express.json());
// 買い物依頼の投稿API
app.post('/api/requests', async (req, res) => {
const { user_id, shop_name, items, preferred_date } = req.body;
try {
const result = await pool.query(
'INSERT INTO requests (user_id, shop_name, items, preferred_date) VALUES ($1, $2, $3, $4) RETURNING *',
[user_id, shop_name, items, preferred_date]
);
// LINE通知を送信(後述)
await sendLineNotification(result.rows[0]);
res.json({ success: true, request: result.rows[0] });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// 依頼一覧取得API
app.get('/api/requests', async (req, res) => {
try {
const result = await pool.query(
'SELECT * FROM requests WHERE status = $1 ORDER BY created_at DESC',
['waiting']
);
res.json(result.rows);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.listen(process.env.PORT || 3000);
- RESTful API: GET(取得)、POST(作成)、PUT(更新)のシンプルな設計
- エラーハンドリング: try-catchで確実にエラーをキャッチ
- 環境変数: データベース接続情報は.envファイルで管理(GitHubに上げない!)
- CORS設定: フロントエンドからのアクセスを許可
💡 セキュリティ: 本番環境では必ずHTTPS化し、helmet.jsでセキュリティヘッダーを設定しましょう。
LINEで通知を受け取れるようにする
- LINE Developersで準備: LINE公式アカウントを作成し、Messaging APIを有効化
- Channel Access Token取得: 管理画面から発行(環境変数で管理)
- Webhook設定: サーバーのURLを登録して、メッセージ受信時の処理を実装
- プッシュ通知: 新しい依頼が投稿されたらサポーターに自動通知
const line = require('@line/bot-sdk');
const client = new line.Client({
channelAccessToken: process.env.LINE_CHANNEL_ACCESS_TOKEN
});
// 新規依頼をサポーターに通知
async function sendLineNotification(request) {
// サポーター全員のLINE IDを取得
const helpers = await pool.query(
"SELECT line_id FROM users WHERE role = 'helper' AND line_id IS NOT NULL"
);
const message = {
type: 'text',
text: `🛒 新しい買い物依頼が届きました!\n\n📍 ${request.shop_name}\n📝 ${request.items}\n\n依頼を確認: https://yourapp.com/requests/${request.request_id}`
};
// 全サポーターに通知
for (const helper of helpers.rows) {
try {
await client.pushMessage(helper.line_id, message);
} catch (err) {
console.error('LINE通知エラー:', err);
}
}
}
⚠️ LINE公式アカウント料金: 月200通まで無料、それ以降は有料プランが必要。地域規模に応じてプラン選択を。
依頼者とサポーターを効率的にマッチング
- 地理的条件: 依頼者とサポーターの距離を計算(徒歩5分圏内を優先)
- 時間的条件: サポーターの対応可能時間帯と依頼の希望日時をマッチ
- 店舗条件: サポーターがよく行く店と依頼の店舗が一致するか
- 自動マッチング: 条件が完全一致したら自動提案、それ以外は手動選択
// サポーター受諾API
app.post('/api/match', async (req, res) => {
const { request_id, helper_id } = req.body;
try {
// トランザクション開始
await pool.query('BEGIN');
// マッチング記録を作成
await pool.query(
'INSERT INTO matches (request_id, helper_id) VALUES ($1, $2)',
[request_id, helper_id]
);
// 依頼のステータスを更新
await pool.query(
"UPDATE requests SET status = 'matched' WHERE request_id = $1",
[request_id]
);
// 依頼者にLINE通知
const request = await pool.query(
'SELECT * FROM requests WHERE request_id = $1',
[request_id]
);
const requester = await pool.query(
'SELECT * FROM users WHERE user_id = $1',
[request.rows[0].user_id]
);
if (requester.rows[0].line_id) {
await client.pushMessage(requester.rows[0].line_id, {
type: 'text',
text: `✅ サポーターが見つかりました!\n\n間もなく連絡があります。`
});
}
await pool.query('COMMIT');
res.json({ success: true });
} catch (err) {
await pool.query('ROLLBACK');
res.status(500).json({ error: err.message });
}
});
💡 スケーラビリティ: 将来的にAIを使った自動マッチング(移動ルート最適化、過去の実績から相性予測)も検討できます。
現金の直接やり取りを避け、透明性のある謝礼システムを
- 地域通貨の導入: 「やすぎコイン」のような独自ポイント制
- 謝礼の目安: 1回の買い物代行で100〜300ポイント(100〜300円相当)
- ポイント利用先: 地域商店での買い物、市の施設利用料などに使える
- 自治体負担: ポイントの原資は自治体の社会福祉予算から拠出
CREATE TABLE local_currency ( transaction_id SERIAL PRIMARY KEY, user_id INT REFERENCES users(user_id), amount INT, -- プラスが受取、マイナスが支払い transaction_type VARCHAR(50), -- 'reward', 'payment', 'bonus' related_match_id INT REFERENCES matches(match_id), created_at TIMESTAMP DEFAULT NOW() ); -- サポーターへの謝礼付与 INSERT INTO local_currency (user_id, amount, transaction_type, related_match_id) VALUES (helper_id, 200, 'reward', match_id); -- 残高確認 SELECT SUM(amount) as balance FROM local_currency WHERE user_id = $1;
💡 他の選択肢: 地域通貨が難しい場合は、ボランティアポイント制度(社協発行)や、商品券での謝礼も検討できます。
システムだけでは成功しない。地域コミュニティとの協働が鍵
- 安来市社会福祉協議会: 民生委員ネットワークを通じた依頼者の募集
- 地域商店との提携: プラーナ、サンアイ、ツルハドラッグなどと協定締結
- 町内会への説明会: サポーター登録を各地区で呼びかけ
- 市役所との連携: 広報誌、市公式サイトでの告知、予算確保
💡 実証実験の進め方: まず1地区(100世帯程度)で3ヶ月運用し、課題を洗い出してから全市展開を。
⚠️ 個人情報の取り扱い: 民生委員や町内会と情報共有する際は、本人同意を必ず取得。書面での同意書を準備しましょう。
システムを継続的に改善していくための指標設定
- 登録ユーザー数: 依頼者・サポーターそれぞれの推移を追跡
- マッチング成功率: 投稿された依頼のうち何%が成立したか
- 平均対応時間: 依頼投稿から完了までの時間
- 利用者満足度: 月次アンケートで★5段階評価
- コスト効率: 1件あたりの運営コスト(人件費含む)
地域福祉推進事業補助金、過疎地域等集落ネットワーク圏形成支援事業など、国・県の補助金で大半をカバー可能。
💡 持続可能性: 2年目以降は地域商店からの手数料収入(1件100円程度)も検討。Win-Winのエコシステムを構築しましょう。
