Skip to content

BBS連携

概要

項目内容
ステータス🔵 提案中
開始日2026/06/23
担当-

提案内容

背景・課題

BBS(pub-api.optimize-business.com)が提供するAPIを使い、GMAC MEO管理画面からアカウント・ロケーションの管理とサイテーション状況の確認ができるようにする。

対象画面と画面遷移フロー

[1] BBSアカウント管理
    ├─ アカウント一覧(検索・ページング)
    ├─ アカウント新規作成
    ├─ [アカウント名クリック] → アカウント詳細・更新
    └─ ["Location"クリック] → [2] ロケーション一覧

[2] ロケーション一覧(選択済みアカウント)
    ├─ [ロケーション名クリック] → ロケーション詳細・更新
    │                                 └─ BBSロケーション ↔ Mappyロケーション マッピング設定
    └─ ["Citation"クリック] → [3] サイテーション一覧

[3] サイテーション一覧(選択済みロケーション)
    └─ 各プラットフォーム / AIリスティング / ボイスアシスタントの掲載状況
画面名概要
BBSアカウント管理BBS上のアカウント一覧・検索・新規作成・編集
ロケーション一覧選択したアカウントのロケーション一覧(料金・連携状態・代理店など)
ロケーション詳細・編集ロケーション新規作成・編集フォーム(35項目)+Mappyロケーションとのマッピング設定
サイテーション一覧ロケーション別のサイテーションページ掲載状況確認

技術設計

データ保存方針

BBSのデータはMappyに保存せず — 必要なときにAPIを呼び出すオンデマンド方式。

BBS側がアカウント・ロケーション・サイテーションのソースオブトゥルースである。Mappyに保存すると、BBS更新時の同期問題が発生し複雑度が増す。この画面は社内運用ツールであるため、APIの数百ms程度の遅延は許容範囲。

また、API仕様書にアクセストークンの有効期限は無期限と明記されており、トークンリフレッシュ機構は不要。

データ保存先理由
BBSアカウント一覧・詳細APIオンデマンド呼び出しBBSがソース
BBSロケーション一覧・詳細APIオンデマンド呼び出しBBSがソース
サイテーション状況APIオンデマンド呼び出しBBSがソース
BBSロケーション ↔ Mappyロケーション マッピングMappy DBに保存Mappy固有の情報、BBSは管理しない

Mappy側のDB変更

新規テーブル mappy_bbs_accounts — BBSアカウントごとのログイン情報とトークンを保存:

カラム備考
idBIGINT UNSIGNED PK
bbs_account_idBIGINT UNSIGNEDBBS側のアカウントID
emailVARCHAR(255)BBSログイン用メールアドレス
passwordVARCHAR(255)暗号化済みパスワード(encrypted)
tokenTEXTアカウント作成後にBBSから取得したトークン
created_at / updated_at / deleted_atTIMESTAMP NULL
  • UNIQUE (bbs_account_id)
  • APIキーは全アカウント共通 → ENV(BBS_API_KEY)に保存、DBには保存しない
  • password復号可能な暗号化(LaravelのAES-256-CBC encrypt()/decrypt())で保存。アカウント作成後にBBSでパスワードを確認できないため
  • アカウント詳細画面ではパスワードを••••••••で表示し、「表示」ボタンで確認可能
  • アカウント新規作成時: POST /v1/create-accountsPOST /v1/login でトークン取得 → tokenカラムに保存

新規テーブル mappy_bbs_location_mappings — MappyロケーションとBBSロケーションのマッピング、既存システムとは完全に独立:

カラム備考
idBIGINT UNSIGNED PK
gbp_location_idBIGINT UNSIGNEDMappy側のロケーションID
bbs_location_idBIGINT UNSIGNEDBBS側のロケーションID
memoVARCHAR(255) NULL運用メモ
created_at / updated_atTIMESTAMP NULL
  • UNIQUE (gbp_location_id) — Mappyロケーション1件につきBBSロケーション1件のみマッピング可
  • BBS側への外部キー制約なし(BBSは外部システムのため)
  • gbp_locationsテーブルは変更しない

認証(Authentication)

操作種別使用トークン保存先
アカウント・ロケーション管理(ROOT)ROOTトークンENV(BBS_ROOT_TOKEN
アカウント別API呼び出しユーザートークンmappy_bbs_accounts.token
  • APIキーはシステム共通 → ENV(BBS_API_KEY
  • ROOTトークンPOST /v1/inside/loginで一度取得 → ENV保存、有効期限なし
  • ユーザートークンはアカウント新規作成時にPOST /v1/loginで自動取得 → mappy_bbs_accountsテーブルに保存

画面別API呼び出し

[1] BBSアカウント管理

操作APIトークン
一覧読み込みGET /v1/pub-accountsROOT
アカウント詳細表示GET /v1/pub-accounts/{account_id}ROOT
アカウント新規作成POST /v1/create-accountsPOST /v1/login(トークン取得・保存)ROOT
アカウント更新PUT /v1/update-accounts/{account_id}ROOT

アカウント新規作成時: POST /v1/create-accounts成功後、POST /v1/loginを呼び出してトークンをmappy_bbs_accountsに保存する。

[2] ロケーション一覧

操作APIトークン
アカウント別ロケーション一覧読み込みGET /v1/pub-locationsaccount_idでフィルター)ROOT
ロケーション詳細表示GET /v1/pub-locations/{location_id}ROOT
ロケーション新規作成POST /v1/create-locationsROOT
ロケーション更新PUT /v1/update-locations/{location_id}ROOT
BBS ↔ Mappyマッピング保存INSERT/UPDATE mappy_bbs_location_mappings—(Mappy DB、BBS API呼び出しなし)

[3] サイテーション一覧

操作APIトークン
ロケーション別サイテーション状況読み込みGET /v1/pub_citation_pages/by-location/{location_id}ユーザートークン(mappy_bbs_accounts.token

サイテーションはそのロケーションを所有するアカウントのユーザートークンを使用。ROOTトークンは使わない。

API対応表

エンドポイントベース: https://pub-api.optimize-business.com 認証: ROOT操作は POST /v1/inside/login で取得したトークン、ユーザー操作は POST /v1/login で取得したトークンを使用。

BBSアカウント管理

操作メソッドURI認証
アカウント一覧取得GET/v1/pub-accountsROOT token
アカウント情報取得GET/v1/pub-accounts/{account_id}ROOT token
アカウント作成POST/v1/create-accountsROOT token
アカウント更新PUT/v1/update-accounts/{account_id}ROOT token

主なリクエストパラメータ(作成・更新): name, email, password, address_line_1〜3, telephone, account_representative, is_additional_line_notification_allowed, memo

ロケーション一覧・詳細・編集

操作メソッドURI認証
ロケーション一覧取得GET/v1/pub-locationsROOT token
ロケーション情報取得GET/v1/pub-locations/{location_id}ROOT token
ロケーション作成POST/v1/create-locationsROOT token
ロケーション更新PUT/v1/update-locations/{location_id}ROOT token

主なリクエストパラメータ(作成・更新):

パラメータ備考
nameStringロケーション名
address_line_1〜3String郵便番号・都道府県・詳細住所
telephoneintハイフン区切り10〜13文字
location_personStringロケーション担当者
place_idStringGoogle Place ID
statusint1:契約 / 2:解約予定 / 3:解約 / 4:準備中 / 5:一時停止
service_idint1:インスタ連携 / 2:Google管理 / 3:インスタ×Google / 4:CMS専用 / 5:IG運用 / 6:IM運用 / 7:リクルート / 8:Synup
contract_starttimestampYYYY-MM-DD HH:MM:SS
contract_update_intervalint契約期間(ヶ月)。status=1,2の場合必須
contract_endtimestamp省略時は当月末日
initial_cost / monthly_costint初期・月額費用
initial_transfer_amount / monthly_transfer_amountint仕切り(初期・月額)
initial_back_amount / monthly_back_amountintバック(初期・月額)
agency_idint代理店(初期値:1=なし)
payment_methodint0:未設定 / 1:カード / 2:口座振替 / 3:請求書 / 4:請求書代行
billing_destinationString請求先
is_initial_configurationintサイテーション: 0:なし / 1:あり / 2:ハイプラン
is_splan / is_owlet / is_onerank / is_win / is_hitosaraintCMSオプション(0:なし / 1:あり)
is_synupint0:なし / 1:あり / 2:あり(飲食業/宿泊業)
synup_serial_numberStringSynupシリアル番号
is_pc_blockint口コミクッションページPCブロック(0:なし / 1:あり)
target_keywordsJSONターゲットキーワード(最大10個)
memoStringメモ

サイテーション一覧

操作メソッドURI認証
サイテーションページ情報取得GET/v1/pub_citation_pages/by-location/{location_id}token

レスポンスにはAIリスティング・ボイスアシスタント・プラットフォームごとの掲載状況(同期済み/準備中/要連携)とインデックス有無・リンクURLが含まれる。

画面モック

BBSアカウント管理

8件 表示中
IDアカウント名adminユーザー住所電話番号インスタ連携GBP管理インスタ × GBP合計契約数月額料金合計メモ操作
51420tanaka@gmail.com東京都港区赤坂3丁目21−1503-4500-745135210¥48,000
51383h.sato@company.co.jp東京都新宿区西新宿2-8-1080-2345-67891214¥16,000
51441suzuki@gmail.com東京都豊島区東池袋1-1-1090-3456-789058417¥85,000
51298misaki.t@outlook.com神奈川県横浜市西区みなとみらい2-2045-567-89010101¥4,800
退会検討中
51247kenta.n@company.jp東京都品川区大崎1-2-203-2345-67892327¥34,000
51203akane.k@mappy-admin.jp東京都千代田区秋葉原1-103-3456-7890812626¥130,000
VIP顧客
51187yuji.ito@ymail.co.jp東京都台東区上野4-1-1070-4567-89012417¥33,600
51152sachiko.y@hotmail.com東京都武蔵野市吉祥寺本町1-10422-12-34561102¥9,600
長期未ログイン

アカウント詳細・編集

ロケーション一覧(アカウント別)

3件
基本情報料金代理店・支払いFB連携GBP連携LINE公式連携IG API連携
IDロケーション住所契約期間電話番号ステータス契約サービス初期費用月額費用仕切り
(初期)
仕切り
(月額)
バック
(初期)
バック
(月額)
サイテーション自動更新
システム
自動更新
(月額)
代理店支払い方法請求先ステータスインスタIDステータス接続メールステータスアクセストークンステータスロギングIDメモ
33944株式会社H2Technology107-0052, 東京都港区赤坂3丁目21−15 東都赤坂ビル 2階A号室2026/04/01 〜 2027/03/3103-4500-7451契約インスタ連携 × GBP管理なしなしなし未選択なしなしなしなしなしH2連携済み連携済み連携済みH2
33945渋谷サンプル店150-0041, 東京都渋谷区神南1丁目2−32026/01/01 〜 2026/12/3103-1234-0001契約GBP管理¥50,000¥9,800¥30,000¥5,000なしなしありあり¥2,000Agency Aクレジット本社未連携連携済み未連携未連携
テスト中
33946新宿テスト法人160-0023, 東京都新宿区西新宿2丁目8−12025/07/01 〜 2026/06/3003-5678-9012解約インスタ連携¥30,000¥4,800未選択未選択なしなしなしなしなし銀行振込担当者連携済み未連携未連携未連携
解約済み

ロケーション詳細・編集

サイテーション一覧

サイテーション数99
株式会社H2Technology

AIリスティング

AI
openai.com
gemini.google.com
perplexity.ai
copilot.microsoft.com
intellychat.com
myndmeld.com

ボイスアシスタントリスティング

アシスタント連携ステータス
CCortana
⏳ 進行中
AAlexa
⏳ 進行中
SSiri
⏳ 進行中

プラットフォームリスティング

プラットフォーム連携ステータスインデックスリンク
HHotfrog
✔ 同期済み🌐 Yes🔗 アクティブ
BBeLocalFocussed
✔ 同期済み🌐 Yes🔗 アクティブ
Aarrivebusiness
✔ 同期済み🌐 Yes🔗 アクティブ
GGoLocalPages
✔ 同期済み🌐 Yes🔗 アクティブ
BBrownBook
✔ 同期済み🌐 Yes🔗 アクティブ
iiGlobal
✔ 同期済み🌐 Yes🔗 アクティブ
OOpenDi.us
✔ 同期済み🌐 Yes🔗 アクティブ
PPassPages
✔ 同期済み🌐 Yes🔗 アクティブ
SSpeedy Local
✔ 同期済み🌐 Yes🔗 アクティブ
LLocalizedListings
✔ 同期済み🌐 Yes🔗 アクティブ
NNAVITIME
✔ 同期済み
MMapion
✔ 同期済み
TTabelog
✔ 同期済み
PPayPay
✔ 同期済み
AAmazon
✔ 同期済み
YYouTube
✔ 同期済み
RRakuten Market
✔ 同期済み
DDiDi
✔ 同期済み
WWaze
✔ 同期済み
UUber
✔ 同期済み
LLife360
✔ 同期済み
MMapFan
✔ 同期済み
LLUUP
✔ 同期済み
Pokemon GO
✔ 同期済み
TToyota
✔ 同期済み
HHonda
✔ 同期済み
BBMW
✔ 同期済み
MMercedes Benz
✔ 同期済み
BBaidu
✔ 同期済み
TTomTom
プラットフォーム側準備中🌐 No
HHere
プラットフォーム側準備中🌐 No
BBing
プラットフォーム側準備中🌐 No
MMG
プラットフォーム側準備中🌐 No
Apple Maps
プラットフォーム側準備中🌐 No🔗 アクティブ
TripAdvisor
アカウント連携が必要🌐 No

概算工数(AI前提)

体制

役割人数担当内容
設計者1名要件確認 → AIに設計書作成指示 → レビュー → 製造へ指示
製造者1名ISSUEを元にAIに作成指示 → コードレビュー → テスト実施 → デプロイ

工数内訳

#作業項目AIリテイクレビュー工数(人日)担当
1要件確認・設計書作成1.0設計者
2ROOT認証・APIクライアント基盤2回0.5日/回1.0製造者
3BBSアカウント管理(一覧・検索・ページング)4回0.5日/回2.0製造者
4アカウント詳細・編集フォーム3回0.5日/回1.5製造者
5ロケーション一覧(グループヘッダー付きテーブル)4回0.5日/回2.0製造者
6ロケーション作成・編集フォーム(35項目・バリデーション)5回0.5日/回2.5製造者
7サイテーション一覧(3セクション表示)2回0.5日/回1.0製造者
8結合テスト・デプロイ3回0.5日/回1.5製造者
9設計レビュー・製造指示1.0設計者
合計13.5設計者2.0日 / 製造者11.5日

スケジュール

タスク担当日数6/236/246/256/266/276/286/296/307/17/27/37/47/57/67/77/87/97/107/117/127/13
要件確認・設計書作成設計者1d
ROOT認証・APIクライアント基盤製造者1d
設計レビュー・製造指示設計者1d
BBSアカウント管理(一覧・検索)製造者2d
アカウント詳細・編集フォーム製造者2d
ロケーション一覧製造者2d
ロケーション作成・編集フォーム製造者3d
サイテーション一覧製造者1d
結合テスト・デプロイ製造者2d

PART 2 — 実装タスク詳細

開発チーム向けのセクション。

技術概要

項目内容
リポジトリmappy-laravel-docker/mappy/laravel(GitLab h2t/mappy、Laravel 5.7 / PHP 7.1)
データ戦略BBS APIをオンデマンド呼び出し、キャッシュなし
新規テーブルmappy_bbs_accountsmappy_bbs_location_mappings
追加ENVBBS_API_KEYBBS_ROOT_TOKENBBS_API_BASE_URL
想定工数約13.5人日(2名:設計者1名 + 製造者1名)

ENV変数

.env.env.exampleに追加:

BBS_API_BASE_URL=https://pub-api.optimize-business.com
BBS_API_KEY=                  # 全アカウント共通のx-api-key
BBS_ROOT_TOKEN=               # POST /v1/inside/login で取得したBearerトークン(有効期限なし)

実装チェックリスト

実装順序: A → (B, C, D 並行) → E → F

A. 基盤(最初に実施 — 他の全タスクが依存)

  • [ ] mappy_bbs_accountsテーブルのマイグレーション — カラム: idbbs_account_id(UNIQUE)、emailpassword(encrypted)、token(TEXT)、created_atupdated_atdeleted_at
  • [ ] mappy_bbs_location_mappingsテーブルのマイグレーション — カラム: idgbp_location_id(UNIQUE)、bbs_location_idmemocreated_atupdated_at
  • [ ] モデル app/Models/Mappy/BbsAccount.phpfillableencrypt()/decrypt()でpasswordをキャスト、SoftDeletes
  • [ ] モデル app/Models/Mappy/BbsLocationMapping.phpfillablebelongsTo(GbpLocation::class)リレーション
  • [ ] サービス app/Services/Mappy/BbsApiService.php — BBS API呼び出しのHTTPクライアントラッパー:
    • デフォルトヘッダー: x-api-key: env('BBS_API_KEY')Content-Type: application/json
    • rootToken()env('BBS_ROOT_TOKEN')を返す
    • userToken($accountId)bbs_account_idBbsAccountからtokenを取得
    • get($uri, $token)post($uri, $data, $token)put($uri, $data, $token)
    • レスポンスステータス >= 400 の場合 BbsApiException をスロー

B. バックエンド — アカウント管理(C、Dと並行)

  • [ ] app/Http/Controllers/Mappy/BbsAccountController.php:
    • index()GET /v1/pub-accounts(ROOTトークン)→ 一覧を返す
    • show($bbsAccountId)GET /v1/pub-accounts/{id} + mappy_bbs_accountsからdecryptしたpassword取得 → storedEmailstoredPassword(マスク済み)を追加で返す
    • store(Request $request) — バリデーション → POST /v1/create-accountsPOST /v1/loginでトークン取得 → mappy_bbs_accountsにINSERT
    • update(Request $request, $bbsAccountId) — バリデーション → PUT /v1/update-accounts/{id}
    • revealPassword($bbsAccountId) — 平文パスワードを返す(decrypt)、「表示」ボタン押下時のみ呼び出し
  • [ ] バリデーション(store/update): name required|max:255、email required|email、password required|min:8、telephone nullable|regex:/^\d{2,4}-\d{2,4}-\d{4}$/
  • [ ] ルート定義:
    php
    Route::prefix('bbs/accounts')->group(function () {
        Route::get('/', 'BbsAccountController@index');
        Route::post('/', 'BbsAccountController@store');
        Route::get('/{id}', 'BbsAccountController@show');
        Route::put('/{id}', 'BbsAccountController@update');
        Route::get('/{id}/password', 'BbsAccountController@revealPassword');
    });

C. バックエンド — ロケーション一覧・詳細(B、Dと並行)

  • [ ] app/Http/Controllers/Mappy/BbsLocationController.php:
    • index($bbsAccountId)GET /v1/pub-locationsaccount_idでフィルター)+ mappy_bbs_location_mappingsをJOINしてマッピング済みか判定
    • show($bbsLocationId)GET /v1/pub-locations/{id} + マッピング情報があれば取得
    • store(Request $request) — バリデーション → POST /v1/create-locations
    • update(Request $request, $bbsLocationId) — バリデーション → PUT /v1/update-locations/{id}
    • mapping(Request $request, $bbsLocationId)gbp_location_idをバリデーション → mappy_bbs_location_mappingsをupsert
  • [ ] バリデーション(store/update): name required、address_line_1 required、location_person required、status required|in:1,2,3,4,5、service_id required|in:1,2,3,4,5,6,7,8、contract_update_interval required_if:status,1,2
  • [ ] ルート定義:
    php
    Route::prefix('bbs/accounts/{accountId}/locations')->group(function () {
        Route::get('/', 'BbsLocationController@index');
        Route::post('/', 'BbsLocationController@store');
        Route::get('/{id}', 'BbsLocationController@show');
        Route::put('/{id}', 'BbsLocationController@update');
        Route::post('/{id}/mapping', 'BbsLocationController@mapping');
    });

D. バックエンド — サイテーション一覧(B、Cと並行)

  • [ ] app/Http/Controllers/Mappy/BbsCitationController.php:
    • index($bbsLocationId) — ロケーションからbbs_account_idを取得 → mappy_bbs_accountsからユーザートークンを取得 → GET /v1/pub_citation_pages/by-location/{id}
  • [ ] ルート定義:
    php
    Route::get('bbs/locations/{locationId}/citations', 'BbsCitationController@index');

E. フロントエンド(A完了後)

  • [ ] resources/js/mappy/views/bbs/AccountList.vue — アカウント一覧、検索、ページング; 「新規作成」「編集」ボタン、LocationListへのリンク
  • [ ] resources/js/mappy/views/bbs/AccountForm.vue — アカウント作成・編集フォーム; パスワードフィールドは••••••••表示、「表示」ボタンでGET /{id}/passwordを呼び出し
  • [ ] resources/js/mappy/views/bbs/LocationList.vue — グループヘッダー付き多カラムテーブル、AccountListへのパンくずリスト、「新規作成」ボタン、CitationListへのリンク
  • [ ] resources/js/mappy/views/bbs/LocationForm.vue — 35項目フォーム + Mappyロケーションマッピングセクション(gbp_location_idのドロップダウン)
  • [ ] resources/js/mappy/views/bbs/CitationList.vue — 3セクション(AIリスティング・ボイスアシスタント・プラットフォーム)、各行に掲載状況とリンクURLを表示

F. QA・運用(最後に実施)

  • [ ] ユニット BbsApiService: U1(ROOTトークンのヘッダーが正しい)、U2(4xxレスポンス → BbsApiExceptionをスロー)、U3(bbs_account_idで正しいuserTokenを取得)
  • [ ] ユニット BbsAccount: U4(保存時にpasswordがencryptされる)、U5(revealPasswordが正しい平文を返す)
  • [ ] 結合テスト: I1(アカウント作成 → mappy_bbs_accountsにトークンが保存される)、I2(ロケーションマッピング → 正しくupsertされる)、I3(サイテーションがROOTトークンでなくユーザートークンを使用)、I4(BBS APIエラー → FEに明確なエラーを返す)
  • [ ] リグレッション: R1(既存画面に影響なし)、R2(gbp_locationsテーブルに変更なし)
  • [ ] BBS_API_KEYBBS_ROOT_TOKENBBS_API_BASE_URL.env.exampleとCI/CDのシークレットに追加