MENU
  • ホーム
  • サービス
  • 記事一覧
  • 問い合わせ
プログラミングやサーバー設定など様々な内容を紹介しています。
HIROTRONの部屋
  • ホーム
  • サービス
  • 記事一覧
  • 問い合わせ
HIROTRONの部屋
  • ホーム
  • サービス
  • 記事一覧
  • 問い合わせ
  1. ホーム
  2. LINE_Messaging_API
  3. 第4話:位置情報でスタンプ獲得!LIFFとLINE Botの連携の裏側

第4話:位置情報でスタンプ獲得!LIFFとLINE Botの連携の裏側

2025 6/25
LINE_Messaging_API さどんでこプロジェクト
2025年6月22日2025年6月25日

私は、友達の紹介でさどんでこプロジェクトのIT担当として様々システム構築などを行っています。今回、スタンプラリー作成でかなり大変だったということから、開発秘話をブログにまとめてみました。興味ある方ぜひ御覧ください。

Sadondeko Project
佐渡を楽しむ デジタルスタンプラリー – さどんでこプロジェクト 佐渡の伝統文化「鬼太鼓」をテーマにしたデジタルスタンプラリーです!両津港をスタート地点に、佐渡金山や大野亀などの主要観光地を巡りながら、各地で鬼太鼓スタンプを集…

第1,2,3話は以下です、合わせてお読みください。

あわせて読みたい
第1話:WordPressじゃ物足りない!?LINE✕鬼太鼓スタンプラリー開発のはじまり 私は、友達の紹介でさどんでこプロジェクトのIT担当として様々システム構築などを行っています。今回、スタンプラリー作成でかなり大変だったということから、開発秘話…
あわせて読みたい
第2話:画像に仕込む魔法!LINEイメージマップとスタンプの格闘記 私は、友達の紹介でさどんでこプロジェクトのIT担当として様々システム構築などを行っています。今回、スタンプラリー作成でかなり大変だったということから、開発秘話…
あわせて読みたい
第3話:地図の中にスタンプ!?Google Maps × Django管理画面の作成 私は、友達の紹介でさどんでこプロジェクトのIT担当として様々システム構築などを行っています。今回、スタンプラリー作成でかなり大変だったということから、開発秘話…
目次

今回のテーマ

  • LIFF(LINE Front-end Framework)で位置情報を取得
  • ユーザーがスタンプ範囲に入ったら、自動でスタンプ獲得
  • スマホ対応にこだわったUI

「GPSでスタンプを押したい!」という課題

鬼太鼓スタンプラリーでは、現地に行くことでスタンプを獲得できるようにしたい。

ただし、LINE Bot単体ではユーザーの現在地を取得することはできません。

そこで着目したのが、LIFF(LINE Front-end Framework)です。

あわせて読みたい
LINE Front-end Framework (LIFF) LINE Front-end Framework(LIFF)は、LINEヤフー株式会社が提供するプラットフォームです。

LIFFとは?LINE × Webの架け橋

LIFFを使えば、LINEの中でWebアプリを動作させることができます。

  • LINEユーザーとしてWebアプリを開く
  • スマホのブラウザAPI(GPSなど)にアクセスできる
  • Web上の判定結果をLINE Botと連携できる

この特性を活かして、LIFF → 位置情報取得 → 範囲内ならスタンプ獲得というフローを構築しました。


スタンプ獲得の流れ

1. LINEのリッチメニューで「GPSをよみこむ」をタップ

2. LIFFアプリ(Web)が起動

3. スマホのGPSから現在地を取得

4. Django APIに現在地を送信

5. 範囲内にあるスタンプがあれば、自動でスタンプ獲得処理が行われる

6. 「スタンプ獲得:{スタンプ名}」メッセージを画面表示


すべてがユーザーのワンタップで完結し、位置情報を活用した自然な体験が実現しました。

GPSをよみこむをタップ

現在地でスタンプを探すをタップ

近くのスタンプを探し、あれば自動で獲得する

範囲判定のロジック

スタンプラリーで重要なのが「ユーザーが本当にその場所にいるかどうか」。

これを判定するために、以下のような処理をサーバー側(Django)に実装しました。

1. 地球上の距離を求める「haversineの公式」

ユーザーの現在地(緯度・経度)と、各スタンプスポットの位置との距離を比較します。

距離の計算には、球面上の2点間の距離を求める有名な公式「haversine(ハバーサイン)」を使います。

from math import radians, sin, cos, sqrt, asin

def haversine(lat1, lon1, lat2, lon2):
    # 度をラジアンに変換
    lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
    # haversineの公式による距離計算
    dlat = lat2 - lat1
    dlon = lon2 - lon1
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a))
    r = 6371000  # 地球の半径(メートル)
    return c * r


この関数で、スポットとの**実際の直線距離(m)**が取得できます。

2. LINEログインの正当性を確認(セキュリティ)

LIFF経由で送られてくるid_tokenを、LINEのAPIを使って検証します。

res = requests.post(
    "https://api.line.me/oauth2/v2.1/verify",
    data={
        "id_token": id_token,
        "client_id": settings.LINE_CHANNEL_ID
    },
    headers={"Content-Type": "application/x-www-form-urlencoded"}
)
line_id = res.json().get("sub")
  • id_tokenはLIFFでのLINEログイン時に取得
  • LINEの公式APIを叩いて正当性チェック
  • LINEのユーザーID(sub)を取得し、DjangoのUserと紐づけ

3. 各スタンプスポットと距離を比較して判定

for spot in StampSpot.objects.all():
    dist = haversine(lat, lon, spot.latitude, spot.longitude)
    if dist <= spot.radius_m:
        _, created = UserStamp.objects.get_or_create(user=user, stamp=spot)
        return JsonResponse({
            "status": "ok",
            "acquired": created,
            "stamp_name": spot.name,
            "stamp_image_url": spot.image.url if spot.image else ""
        })
  • 登録されているすべてのスタンプスポットに対して、
  • haversine() で現在地との距離を算出
  • spot.radius_m以内であれば、獲得処理を実行
  • すでに獲得済みならacquired: falseで返す

このようにして、実際にその場所に来た人だけがスタンプを獲得できるようになっています。

レスポンスの例(範囲内で新規獲得)

{
  "status": "ok",
  "acquired": true,
  "stamp_name": "両津港",
  "stamp_image_url": "https://.../ryotsukou.png"
}

レスポンスの例(範囲外)

{
  "status": "no_match"
}


このように、LIFFから送られてくる位置情報をサーバー側で精密に検証し、正確でセキュアなスタンプ獲得体験を提供しています。

UIにもこだわったLIFFページ ~「押す快感」と「達成感」を1画面で~

「現地でGPSを使って、ただスタンプをもらえるだけじゃ面白くない」

スタンプラリーの体験を”ワクワクする瞬間”に昇華させるため、LIFFページのUI・演出に特に力を入れました。


Bootstrapでつくるシンプルなレイアウト

  • 全体はBootstrap 5をベースに構築
  • ボタン、メッセージ表示、レスポンシブ対応を簡潔に実装
  • containerで整った中央配置、alertで状態を直感的に伝達
  • ユーザーが迷わず1ボタンで完了する導線を追求
<button id="check-location" class="btn btn-primary w-100 mb-3">
  現在地でスタンプを探す
</button>

<div id="message" class="alert alert-secondary" role="alert">
  👆 上のボタンをタップして、スタンプを探してください。
</div>

ユーザーに迷いがないよう、「今やること」「結果」「次の動作」を視覚的に区切って表示するよう設計しました。


スタンプ獲得のアニメーションは「体験のハイライト」

LIFFページのこだわりの1つは、スタンプを獲得したときのアニメーション演出です。

ポイント:

その後は控えめな「確認メッセージ」で余韻を残す

画面中央に、スタンプ画像をポップアップ表示

@keyframes pop を使用した拡大・回転アニメーション

アニメーション終了後、獲得メッセージがふわっと表示

@keyframes pop {
  0% {
    transform: scale(7) rotate(-20deg);
    opacity: 0.8;
  }
  100% {
    transform: scale(1) rotate(0deg);
    opacity: 1;
  }
}
stampImg.style.animation = "pop 2s ease-out forwards";

演出の流れ:

  1. スタンプ画像が中心にドーンと出現(scale 7 → 1)
  2. 数秒間そのまま表示
  3. 獲得メッセージを表示
  4. 自動で非表示 → 完了メッセージへ遷移

ユーザーに「やった!スタンプ獲得した!」という視覚的な達成感を届ける工夫です。


スマホ1つで鬼太鼓スタンプラリーが完成!

この仕組みによって、ユーザーは:

  • アプリインストール不要
  • 現地に行ってワンタップでスタンプ獲得
  • 位置を自動判定してくれる、直感的な体験
  • スタンプカードにスタンプが貯まる喜び

をLINE上でそのまま味わえるようになりました。


次なる展望:位置情報 × Web体験の拡張へ

このLIFF連携が完成したことで、スタンプラリーは「現地体験」と「デジタル収集」が完全にリンクした形になりました。

次はこんなアイデアも視野に入れています:

  • 獲得数に応じた称号やバッジの導入
  • 全スタンプ制覇で限定動画が視聴可能
  • 他地域にも広げた鬼太鼓ラリーの全国展開

開発秘話、これにて完結!

4話にわたりお届けした開発裏話、いかがでしたでしょうか?

WordPressから始まり、LINE × Django × LIFFという独自スタイルにたどり着いたこのプロジェクト。

技術だけでなく、地域への想いを形にする手段としての開発の魅力も伝えられたら嬉しいです。

あと、ぜひ鬼太鼓スタンプラリーに参加してください!!

Sadondeko Project
佐渡を楽しむ デジタルスタンプラリー – さどんでこプロジェクト 佐渡の伝統文化「鬼太鼓」をテーマにしたデジタルスタンプラリーです!両津港をスタート地点に、佐渡金山や大野亀などの主要観光地を巡りながら、各地で鬼太鼓スタンプを集…
LINE友達登録でスタンプラリー開始!
LINE_Messaging_API さどんでこプロジェクト
Bootstrap Django Javascript LIFF LINE LINE Messaging API さどんでこプロジェクト
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
  • 第3話:地図の中にスタンプ!?Google Maps × Django管理画面の作成
  • Django ✕ LINE Messaging APIでローディングアニメーションを出す方法

この記事を書いた人

hiroto121022のアバター hiroto121022

医学生でありながら、さどんでこプロジェクトのITリーダーを務めるフルスタック開発者。LINE BotやGPS連携スタンプラリー、NFT販売サイトなどをすべて独学で開発。使用言語はPython、Typescript、Javascript。Django、Next.js、Reactなどのフレームワークを駆使し、サーバー構築・デプロイ・SSL対応まで一貫して担当。AIによるアートのアニメーション化にも取り組み、伝統文化とテクノロジーを融合させた新しい地域体験の創出に挑戦している。

関連記事

  • Django ✕ LINE Messaging APIでローディングアニメーションを出す方法
    2025年6月25日
  • 第3話:地図の中にスタンプ!?Google Maps × Django管理画面の作成
    2025年6月22日
  • 第2話:画像に仕込む魔法!LINEイメージマップとスタンプの格闘記
    2025年6月22日
  • 第1話:WordPressじゃ物足りない!?LINE✕鬼太鼓スタンプラリー開発のはじまり
    2025年6月22日

コメント

コメント一覧 (1件)

  • LINE API × 鬼太鼓スタンプラリー誕生秘話③ 座標管理とDjango管理画面 - HIROTRONの部屋 より:
    2025年6月22日 9:46 PM

    […] 第4話:位置情報でスタンプ獲得!LIFFとLINE Botの連携の裏側 今回のテーマ LIFF(LINE Front-end Framework)で位置情報を取得 […]

    返信

コメントする コメントをキャンセル

hiroto121022
医学生でありながら、さどんでこプロジェクトのITリーダーを務めるフルスタック開発者。LINE BotやGPS連携スタンプラリー、NFT販売サイトなどをすべて独学で開発。使用言語はPython、Typescript、Javascript。Django、Next.js、Reactなどのフレームワークを駆使し、サーバー構築・デプロイ・SSL対応まで一貫して担当。
GitHub
新着記事
  • Django ✕ LINE Messaging APIでローディングアニメーションを出す方法
  • 第4話:位置情報でスタンプ獲得!LIFFとLINE Botの連携の裏側
  • 第3話:地図の中にスタンプ!?Google Maps × Django管理画面の作成
  • 第2話:画像に仕込む魔法!LINEイメージマップとスタンプの格闘記
  • 第1話:WordPressじゃ物足りない!?LINE✕鬼太鼓スタンプラリー開発のはじまり

© HIROTRONの部屋.

目次