<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
  <generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator>
  <link href="https://jp.zhgchg.li/feed.xml" rel="self" type="application/atom+xml" />
  <link href="https://jp.zhgchg.li/" rel="alternate" type="text/html" hreflang="ja" />
  <updated>2026-06-14T14:50:50+08:00</updated>
  <id>https://jp.zhgchg.li/feed.xml</id>
  <title type="html">ZhgChgLi テック &amp;amp; トラベル</title>
  <subtitle>iOS 開発、自動化、オープンソース、そして旅の記録。 台湾からの iOS / Web デベロッパーによるブログ。</subtitle><author>
    <name>ZhgChgLi</name><email>zhgchgli@gmail.com</email>
  </author><entry>
    <title type="html">AI 協作で資料構造RFC作成｜多言語実装と技術設計の深掘り</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ai-%E5%8D%94%E4%BD%9C%E3%81%A7%E8%B3%87%E6%96%99%E6%A7%8B%E9%80%A0rfc%E4%BD%9C%E6%88%90-%E5%A4%9A%E8%A8%80%E8%AA%9E%E5%AE%9F%E8%A3%85%E3%81%A8%E6%8A%80%E8%A1%93%E8%A8%AD%E8%A8%88%E3%81%AE%E6%B7%B1%E6%8E%98%E3%82%8A-f7bec8f79c08/" rel="alternate" type="text/html" title="AI 協作で資料構造RFC作成｜多言語実装と技術設計の深掘り" />
    <published>2026-05-10T15:01:01+08:00</published>
    <updated>2026-05-10T15:28:40+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/f7bec8f79c08</id><summary type="html">技術者向けにAIを活用した資料構造RFCの作成過程を解説。問題抽象からアルゴリズム選定、Ruby・Swift実装まで、AIと共に進める技術研究の具体例を紹介します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="iosアプリ開発" /><category term="leetcode" /><category term="claudeコード" /><category term="aiエージェント" /><category term="アルゴリズム" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/f7bec8f79c08/1*H5MBf1d1kEqBQnqtG9-zgg.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ai-%E5%8D%94%E4%BD%9C%E3%81%A7%E8%B3%87%E6%96%99%E6%A7%8B%E9%80%A0rfc%E4%BD%9C%E6%88%90-%E5%A4%9A%E8%A8%80%E8%AA%9E%E5%AE%9F%E8%A3%85%E3%81%A8%E6%8A%80%E8%A1%93%E8%A8%AD%E8%A8%88%E3%81%AE%E6%B7%B1%E6%8E%98%E3%82%8A-f7bec8f79c08/"><![CDATA[<h3 id="aiは単なるアプリ開発だけでなくaiと協力してデータ構造rfcと多言語実装を完成させる"><strong>AIは単なるアプリ開発だけでなく：AIと協力してデータ構造RFCと多言語実装を完成させる</strong></h3>

<p>Rangeable RFC を例に、問題の抽象化、アルゴリズムの選択、意味の定義から Ruby / Swift の参考実装まで、AI がどのようにより深い技術研究と設計に関わったかを記録します。</p>

<p><img src="/assets/f7bec8f79c08/1*H5MBf1d1kEqBQnqtG9-zgg.webp" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/f7bec8f79c08/1*H5MBf1d1kEqBQnqtG9-zgg.jpeg" /></p>

<h3 id="背景">背景</h3>

<p>数週間前、<a href="https://zhgchg.li/" target="_blank">個人サイト</a> の再設計のためにClaude Code Maxを使い始め、その後AIとGoogle Apps Scriptを組み合わせて、古いiPhoneを活用した個人用デスクトップダッシュボードデッキを作りました。今週からは、以前作成したオープンソースプロジェクトに目標を切り替え、AIを使って手作業で書いたコードをリファクタリングし、効率化、ドキュメントの補充、テストの充実を図っています。</p>

<blockquote>
  <p><strong><em>要約</em></strong></p>
</blockquote>

<blockquote>
  <p><em>まず AI を使っていくつかのオープンソースプロジェクトのアプリケーション層をリファクタリングし、それがきっかけでより深い Foundation のデータ構造設計に取り組むことになった。</em></p>
</blockquote>

<h4 id="linkyee-あなた専用のリンクページ"><a href="https://github.com/ZhgChgLi/linkyee" target="_blank">Linkyee— あなた専用のリンクページ</a></h4>

<p>完全カスタマイズ可能で、100%無料のオープンソースLinkTree代替品 — GitHub Pagesに直接デプロイ。</p>

<p><a href="https://github.com/ZhgChgLi/linkyee" target="_blank"><img src="https://repository-images.githubusercontent.com/877945203/333b5db1-e5e7-4d71-8b53-986a60e75033" alt="" /></a></p>

<p>最初に改善したのは、以前作成した類似 Linktree の無料オープンソース自架版で、AIを使って構造を再構築し、いくつかのテーマを追加し、内蔵プラグインを増やし、ユーザーが簡単にカスタマイズできるDesign AIスキルを追加し、ローカルテスト環境も補強しました。</p>

<h4 id="zmediumtomarkdown"><a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a></h4>

<p>Mediumの投稿をクリーンなMarkdownとしてダウンロードし、構造、画像、リンク、コードブロック、一般的な埋め込みをプレーンなMarkdownやJekyllのワークフロー用に保持します。</p>

<p>あなたのために記事のすべての内容（画像、埋め込みコード、YouTubeリンクなど）をダウンロードし、Markdown形式に変換します。画像もすべてダウンロードして <code class="language-plaintext highlighter-rouge">./assets</code> フォルダに保存します。</p>

<p><a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank"><img src="https://repository-images.githubusercontent.com/493527574/9b5b7025-cc95-4e81-84a9-b38706093c27" alt="" /></a></p>

<p>二つ目は、私が4年以上使い続け、メンテナンスしているプロジェクトです — 「Mediumの記事をダウンロードしてMarkdown形式に変換する」ツールで、後期はほぼMediumを記事編集のバックエンドとして使い、このツールで原文をダウンロード・変換してから私の<a href="https://zhgchg.li/" target="_blank">自前のサイト</a>にアップロードしています。</p>

<p>このプロジェクトは私のウェブサイトと Medium の重要な架け橋であり、途切れてはいけません。最初のバージョンを開発したときには多くの時間と労力を費やしましたし、ここ数年は細かい問題を修正し続けてきましたが、全体の設計を見直して最適化するのは久しぶりです。</p>

<p>同様にまずは AI による最適化応用から始め、手作業で書いたレンダリングロジックのリファクタリングとテスト補強を依頼しました。また、Medium の Cloudflare Anti-bot 対応も強化し、ユーザーが Medium のクローラー遮断に遭遇した際に、Chrome でログインしてクッキーを自動取得し、その後自動で処理を実行できるようにしました。</p>

<h4 id="mcp-medium-reader"><a href="https://github.com/ZhgChgLi/mcp-medium-reader" target="_blank">mcp-medium-reader</a></h4>

<p>最後に AI は Medium.com 記事の Reader MCP サービスも構築しました。</p>

<p><a href="https://github.com/ZhgChgLi/mcp-medium-reader" target="_blank"><img src="https://opengraph.githubassets.com/be5c8e0489d9add1b623ab52d36b56df26fe36b6d911ba3df2be6bf6c03fe966/ZhgChgLi/mcp-medium-reader" alt="" /></a></p>

<p>主に基本的な変換サービスである <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a> はすでに完成しており、MCP はそれを呼び出すラッパー層に過ぎません。</p>

<p>解決した問題は、ChatGPT、Codex、Claude、Claude Code などの AI に Medium の記事を渡すと、Medium の Cloudflare Anti-bot によってコンテンツのクロールがブロックされやすく、AI が記事を直接読み取れないことです。たとえ読み取れても、HTML を読み取るだけで、AI にとって扱いやすい Markdown 形式ではありません。</p>

<blockquote>
  <p><a href="https://github.com/ZhgChgLi/mcp-medium-reader" target="*blank"><em>mcp-medium-reader</em></a> <em>AIが制限を突破し、Markdown形式のMedium記事を読み取り、トークンを節約しながらAIの理解力を向上させます。</em></p>
</blockquote>

<h3 id="ラベル付き区間集合の問題"><strong>ラベル付き区間集合の問題</strong></h3>

<blockquote>
  <p><em>当時 <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a> を作っていたときに、<strong>この Foundation のデータ構造設計（アルゴリズム）問題</strong> に直面しました。その時は余裕も能力もなく解決できませんでしたが、今は AI があるので、AI を使ってこの問題を解決してみようと思いました。</em></p>
</blockquote>

<h4 id="ケース1--mediumのレンダリング問題">ケース1 — Mediumのレンダリング問題</h4>

<p><strong>Medium.com の GraphQL API が返す記事内容データは以下の形式です：</strong></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"text"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."</span><span class="p">,</span><span class="w">
  </span><span class="nl">"markups"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"A"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"start"</span><span class="p">:</span><span class="w"> </span><span class="mi">169</span><span class="p">,</span><span class="w">
      </span><span class="nl">"end"</span><span class="p">:</span><span class="w"> </span><span class="mi">207</span><span class="p">,</span><span class="w">
      </span><span class="nl">"href"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://zhgchg.li/posts/f6713ba3fee3/"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"anchorType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"LINK"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"userId"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"linkMetadata"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Markup"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"STRONG"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"start"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w">
      </span><span class="nl">"end"</span><span class="p">:</span><span class="w"> </span><span class="mi">29</span><span class="p">,</span><span class="w">
      </span><span class="nl">"href"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"anchorType"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"userId"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"linkMetadata"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Markup"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"EM"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"start"</span><span class="p">:</span><span class="w"> </span><span class="mi">15</span><span class="p">,</span><span class="w">
      </span><span class="nl">"end"</span><span class="p">:</span><span class="w"> </span><span class="mi">55</span><span class="p">,</span><span class="w">
      </span><span class="nl">"href"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"anchorType"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"userId"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"linkMetadata"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Markup"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"STRONG"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"start"</span><span class="p">:</span><span class="w"> </span><span class="mi">69</span><span class="p">,</span><span class="w">
      </span><span class="nl">"end"</span><span class="p">:</span><span class="w"> </span><span class="mi">88</span><span class="p">,</span><span class="w">
      </span><span class="nl">"href"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"anchorType"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"userId"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"linkMetadata"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Markup"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><strong>わかりやすく翻訳：</strong></p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="m">0</span><span class="p">,</span><span class="m">14</span><span class="p">]</span>    <span class="n">STRONG</span>       <span class="p">=</span> <span class="n">Lorem</span> <span class="n">ipsum</span> <span class="n">dol</span>
<span class="p">[</span><span class="m">15</span><span class="p">,</span><span class="m">29</span><span class="p">]</span>   <span class="n">STRONG</span> <span class="p">+</span> <span class="n">EM</span>  <span class="p">=</span> <span class="n">or</span> <span class="n">sit</span> <span class="n">amet</span><span class="p">,</span> <span class="n">co</span>
<span class="p">[</span><span class="m">30</span><span class="p">,</span><span class="m">55</span><span class="p">]</span>   <span class="n">EM</span>           <span class="p">=</span> <span class="n">nsectetur</span> <span class="n">adipiscing</span> <span class="n">elit</span><span class="p">,</span>
<span class="p">[</span><span class="m">56</span><span class="p">,</span><span class="m">68</span><span class="p">]</span>   <span class="n">normal</span>       <span class="p">=</span>  <span class="n">sed</span> <span class="k">do</span> <span class="n">eiusm</span>
<span class="p">[</span><span class="m">69</span><span class="p">,</span><span class="m">88</span><span class="p">]</span>   <span class="n">STRONG</span>       <span class="p">=</span> <span class="n">od</span> <span class="n">tempor</span> <span class="n">incididunt</span>
<span class="p">[</span><span class="m">89</span><span class="p">,</span><span class="m">168</span><span class="p">]</span>  <span class="n">normal</span>       <span class="p">=</span>  <span class="n">ut</span> <span class="n">labore</span> <span class="n">et</span> <span class="n">dolore</span> <span class="n">magna</span> <span class="n">aliqua</span><span class="p">.</span> <span class="n">Ut</span> <span class="n">enim</span> <span class="n">ad</span> <span class="n">minim</span> <span class="n">veniam</span><span class="p">,</span> <span class="n">quis</span> <span class="n">nostrud</span> <span class="n">exercit</span>
<span class="p">[</span><span class="m">169</span><span class="p">,</span><span class="m">207</span><span class="p">]</span> <span class="n">A</span>            <span class="p">=</span> <span class="n">ation</span> <span class="n">ullamco</span> <span class="n">laboris</span> <span class="n">nisi</span> <span class="n">ut</span> <span class="n">aliquip</span> <span class="n">e</span>
</code></pre></div></div>

<p><strong>期待されるレンダリング結果：</strong></p>

<p><img src="/assets/f7bec8f79c08/1*0cOIQ8YgvcrBZKUdCEaxGw.webp" alt="" loading="lazy" decoding="async" width="652" height="99" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NTIiIGhlaWdodD0iOTkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/f7bec8f79c08/1*0cOIQ8YgvcrBZKUdCEaxGw.png" /></p>

<blockquote>
  <p><em>注意：Medium の元データの end の意味は実際の API 定義に従って変換する必要があります；本文では以降、Rangeable RFC の閉区間の意味で説明します。</em></p>
</blockquote>

<h4 id="問題">問題</h4>

<ul>
  <li>
    <p><strong>区間の重ね合わせ</strong><br />
同じ区間に複数の状態が重なることがあります。例えば、[15,29] は STRONG + EM です。</p>
  </li>
  <li>
    <p><strong>区間の交錯</strong><br />
極端な場合、ユーザーが交錯するスタイルを設定することがあります。例えば、[0,29] は STRONG、[15,55] は EM です。</p>
  </li>
</ul>

<p><img src="/assets/f7bec8f79c08/1*nagAmJcFkHpMSdbELnT7Mg.webp" alt="" loading="lazy" decoding="async" width="386" height="77" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzODYiIGhlaWdodD0iNzciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/f7bec8f79c08/1*nagAmJcFkHpMSdbELnT7Mg.png" /></p>

<ul>
  <li><strong>区間の連続マージ</strong><br />
データが [0,12] は STRONG / [12,29] は STRONG の場合、[0,29] は STRONG にマージする必要があります。</li>
</ul>

<p>区間の重なりや連続した区間の結合は比較的処理しやすいですが、一番厄介なのは区間が交錯して閉じる場合の処理です。インデックス通りにレンダリングすると <code class="language-plaintext highlighter-rouge">**AA_AA**BBB_</code> のようになり、正しくは開閉を調整して <code class="language-plaintext highlighter-rouge">**AA_AA_**_BBB_</code> としなければなりません。</p>

<p>iOS 開発者で <code class="language-plaintext highlighter-rouge">NSAttributedString attributes</code> を使ったことがある方も同じ問題に直面しますが、Apple Foundation は区間のマージや重複処理をうまく処理してくれています。</p>

<blockquote>
  <p><em>当時もかなり長い時間考え込んでしまい、本が役に立たないと痛感しました。普段あまり問題演習をしていなかったため、実際に使う場面で武器がありませんでした。その時は最も力技のウォークスルーで解決しましたが、正確ではあったものの性能とコードの質が非常に悪かったです。</em></p>
</blockquote>

<h4 id="関連する-leetcode-の問題タイプ">関連する LeetCode の問題タイプ</h4>

<ul>
  <li><strong>区間のマージ</strong></li>
</ul>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">56</span><span class="p">.</span> <span class="err">区間のマージ</span>
<span class="mi">57</span><span class="p">.</span> <span class="err">区間の挿入</span>
</code></pre></div></div>

<p><strong>用途：</strong> STRONG [0,12] と STRONG [13,29] を結合して STRONG [0,29] にする。</p>

<ul>
  <li><strong>スイープライン</strong></li>
</ul>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">253.</span> 会議室 II
<span class="p">731.</span> マイカレンダー II
<span class="p">732.</span> マイカレンダー III
<span class="p">1094.</span> カープーリング
<span class="p">1851.</span> 各クエリを含む最小間隔
</code></pre></div></div>

<p><strong>用途：</strong></p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">STRONG</span> <span class="o">[</span><span class="err">0</span><span class="o">,</span><span class="err">29</span><span class="o">]</span>
<span class="nt">EM</span>     <span class="o">[</span><span class="err">15</span><span class="o">,</span><span class="err">55</span><span class="o">]</span>
<span class="nt">A</span>      <span class="o">[</span><span class="err">169</span><span class="o">,</span><span class="err">207</span><span class="o">]</span>
</code></pre></div></div>

<p>〜へ</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">0</span>    <span class="nt">open</span> <span class="nt">STRONG</span>
<span class="err">15</span>   <span class="nt">open</span> <span class="nt">EM</span>
<span class="err">30</span>   <span class="nt">close</span> <span class="nt">STRONG</span>
<span class="err">56</span>   <span class="nt">close</span> <span class="nt">EM</span>
<span class="err">169</span>  <span class="nt">open</span> <span class="nt">A</span>
<span class="err">208</span>  <span class="nt">close</span> <span class="nt">A</span>
</code></pre></div></div>

<ul>
  <li><strong>差分配列（Difference Array）ですが、純粋な数値の差分ではありません</strong></li>
</ul>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">370.</span> Range Addition
<span class="p">1109.</span> Corporate Flight Bookings
<span class="p">1094.</span> Car Pooling
</code></pre></div></div>

<p><strong>用途：</strong> アクティブなマークアップセットの管理</p>

<ul>
  <li><strong>区間分割 / セグメント構築</strong></li>
</ul>

<p><strong>用途：</strong></p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">STRONG</span> <span class="o">[</span><span class="err">0</span><span class="o">,</span><span class="err">29</span><span class="o">]</span>
<span class="nt">EM</span>     <span class="o">[</span><span class="err">15</span><span class="o">,</span><span class="err">55</span><span class="o">]</span>
</code></pre></div></div>

<p>〜へ</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span><span class="err">0</span><span class="o">,</span><span class="err">14</span><span class="o">]</span>   <span class="nt">STRONG</span>
<span class="o">[</span><span class="err">15</span><span class="o">,</span><span class="err">29</span><span class="o">]</span>  <span class="nt">STRONG</span> <span class="o">+</span> <span class="nt">EM</span>
<span class="o">[</span><span class="err">30</span><span class="o">,</span><span class="err">55</span><span class="o">]</span>  <span class="nt">EM</span>
</code></pre></div></div>

<p><strong>他に使われた問題タイプ、データ構造：</strong></p>

<ul>
  <li>
    <p>イベントのソート</p>
  </li>
  <li>
    <p>区間分割 / セグメント分割</p>
  </li>
  <li>
    <p>スタック / 括弧のマッチング</p>
  </li>
  <li>
    <p>二分探索</p>
  </li>
  <li>
    <p>Ordered Set / LinkedHashSet</p>
  </li>
  <li>
    <p>正規化</p>
  </li>
</ul>

<h4 id="ケース2--avplayer-キャッシュ区間の問題">ケース2 — AVPlayer キャッシュ区間の問題</h4>

<p>上記の Medium での区間問題は、実は私も以前似たような問題に直面しました。開発中の「<a href="/posts/zrealm-dev/avplayer-本地cache機能の完全ガイド-avurlassetとavassetresourceloaderdelegate活用法-6ce488898003/">AVPlayer ローカルで再生しながらキャッシュする時</a>」でも同様の課題がありました。</p>

<p>ストリーミングデータは連続していないため、サイズが1000のデータに対して、AVPlayerは <code class="language-plaintext highlighter-rouge">[0,100] [300–500] [150, 200]…</code> のような連続していない、または交差するデータを要求することがあります。</p>

<p><img src="/assets/f7bec8f79c08/1*9cNp02AnTbilWCpadldfBw.webp" alt="" loading="lazy" decoding="async" width="1189" height="801" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTg5IiBoZWlnaHQ9IjgwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/f7bec8f79c08/1*9cNp02AnTbilWCpadldfBw.png" /></p>

<p>以上の図を例に、<strong>現在のデータ区間：</strong> <code class="language-plaintext highlighter-rouge">[250,566] [850,959]</code> と仮定すると、理想的には：</p>

<ul>
  <li>
    <p><strong>AVPlayer に [0,300] を問い合わせた時：</strong> [0,249] はリモートから取得、[250,300] はローカルから取得</p>
  </li>
  <li>
    <p><strong>AVPlayer が [350, 920] を問い合わせたとき：</strong> [350,566] はローカルから取得、[567,849] はリモートから取得、[850,920] はローカルから取得</p>
  </li>
</ul>

<p>当時も同様に区間計算の問題に直面しました — <strong>Covered / Uncovered Interval Query</strong>、ただし Medium の問題より簡単で、こちらはバイナリデータの0と1の区別だけで、結果の計算だけが必要でした。</p>

<blockquote>
  <p>*当時も一時的に解決できませんでした。なぜなら、AVPlayer の再生しながらキャッシュする機能の開発にほとんどの時間を費やしたからです。また、その時のシナリオは音声で、ファイル自体が小さかったため、<strong>区間にデータがなければ全て取得して上書きする方法を先に採用しました — 詳細は元記事「 <a href="/posts/zrealm-dev/avplayer-本地cache機能の完全ガイド-avurlassetとavassetresourceloaderdelegate活用法-6ce488898003/">AVPlayer 本地 Cache 実装攻略｜使用 AVAssetResourceLoaderDelegate で iOS 音楽ストリーミングの通信量を節約</a> 」をご参照ください。</strong> *</p>
</blockquote>

<h3 id="全体的な協力プロセス">全体的な協力プロセス</h3>

<p><img src="/assets/f7bec8f79c08/1*t1oXXy1czhI_yV0LKBVf0Q.webp" alt="" loading="lazy" decoding="async" width="1672" height="941" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNjcyIiBoZWlnaHQ9Ijk0MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/f7bec8f79c08/1*t1oXXy1czhI_yV0LKBVf0Q.jpeg" /></p>

<h3 id="aiを使ったfoundationデータ構造設計の実装">AIを使ったFoundationデータ構造設計の実装</h3>

<h4 id="ツール">ツール</h4>

<ul>
  <li>
    <p>Claude Code Max</p>
  </li>
  <li>
    <p>努力: 最大限度</p>
  </li>
  <li>
    <p>モデル: Opus 4.7</p>
  </li>
</ul>

<h4 id="フロー">フロー</h4>

<ul>
  <li>
    <p>まずは AI Plan Mode を使って RFC 作成計画を立てる</p>
  </li>
  <li>
    <p>AIに研究を開始させ、2つのエージェント役割を設定してください：一人はRFCの研究と執筆を担当する大学院生、もう一人はアルゴリズムの効率性と妥当性のレビューに専念する教授（レビューは承認されるまで継続）。</p>
  </li>
  <li>
    <p>研究生はまず Medium のケースを実験として、Ruby で開発してみることができます。</p>
  </li>
  <li>
    <p>最終生成された RFC.md ファイル</p>
  </li>
  <li>
    <p>他のエージェントに各言語での実装を任せる（私は ZMediumToMarkdown は Ruby、AVPlayer は iOS Swift の問題）</p>
  </li>
</ul>

<h4 id="1-aiによるデータ構造rfcの検討--rangeable-rfc">1. AIによるデータ構造RFCの検討 — Rangeable RFC</h4>

<p><strong>プロンプト（計画モード）：</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plan

英語を使用し、英語の論文研究を参考にしてRFC実装ドキュメントを作成してください。後で他の言語がこのドキュメントに従って実装できるようにします。作成期間中はRubyを実験言語として使用しても構いません。
すべてのデータ構造とアルゴリズムを研究し、時間と空間効率のバランスが最も良いアルゴリズムを見つけて要件を達成してください。
ツール名：Rangeable
機能：ジェネリックオブジェクトの連続および非連続集合を計算する。
例：
var strings:Rangeable&lt;String&gt; <span class="o">=</span> <span class="o">[]</span>
strings.insert<span class="o">(</span>Strong<span class="o">()</span>, start: 2, end: 5<span class="o">)</span> // 2-5 Strong
strings.insert<span class="o">(</span>Strong<span class="o">()</span>, start: 3, end: 7<span class="o">)</span> // 3-7 Strong
strings.insert<span class="o">(</span>Strong<span class="o">()</span>, start: 9, end: 11<span class="o">)</span> // 9-11 Strong
strings.insert<span class="o">(</span>Italic<span class="o">()</span>, start: 3, end: 8 <span class="o">)</span> // 3-8 Italic

// 使用例:
Strong<span class="o">()</span>.getRange<span class="o">(</span>from: strings<span class="o">)</span> -&gt; <span class="o">[{</span>2,7<span class="o">}</span>,<span class="o">{</span>9-11<span class="o">}]</span>
Italic<span class="o">()</span>.getRange<span class="o">(</span>from strings<span class="o">)</span> -&gt; <span class="o">[{</span>3,8<span class="o">}]</span>
//
strings[4].objs -&gt; <span class="o">[</span>Strong<span class="o">()</span>, Italic<span class="o">()]</span>
strings[8].objs -&gt; <span class="o">[</span>Italic<span class="o">()]</span>
strings[10].objs -&gt; <span class="o">[</span>Strong<span class="o">()]</span>
//
Strong, Italic はそれ自体もジェネリックですが、ここでは例として挙げています
//

実際にRFCを作成する際は、サブエージェントを使い、研究生が実装方法の研究とRFCの執筆を担当し、教授が学術的またはより深いアルゴリズムの観点から研究生エージェントの成果をレビューします。教授エージェントに却下された場合は再度研究してRFCを書き直してください。
まずは ./RubyRangeable にRuby実装、./SwiftRangeable にSwift実装を作成してください。
トークンやリソースを惜しまず研究に使って構いません。
//
実際の適用例：../ZMediumToMarkdown 内の MarkupStyleRender.rb
現在はMedium GraphQLが返すParagraphsを解析しています
<span class="o">{</span><span class="s2">"id"</span>: <span class="s2">"f30dc1c4fe6c_19"</span>, <span class="s2">"name"</span>: <span class="s2">"b2ba"</span>, <span class="s2">"type"</span>: <span class="s2">"BQ"</span>, <span class="s2">"href"</span>: null, <span class="s2">"layout"</span>: null, <span class="s2">"metadata"</span>: null, <span class="s2">"text"</span>: <span class="s2">"A notification webhook is an endpoint you create on your server.</span><span class="se">\n</span><span class="s2">通知型 Webhook は自分のサーバー上に作成するエンドポイントです。"</span>, <span class="s2">"hasDropCap"</span>: null, <span class="s2">"dropCapImage"</span>: null, <span class="s2">"markups"</span>: <span class="o">[{</span><span class="s2">"type"</span>: <span class="s2">"EM"</span>, <span class="s2">"start"</span>: 0, <span class="s2">"end"</span>: 104, <span class="s2">"href"</span>: null, <span class="s2">"anchorType"</span>: null, <span class="s2">"userId"</span>: null, <span class="s2">"linkMetadata"</span>: null, <span class="s2">"__typename"</span>: <span class="s2">"Markup"</span><span class="o">}]</span>, <span class="s2">"__typename"</span>: <span class="s2">"Paragraph"</span>, <span class="s2">"codeBlockMetadata"</span>: null, <span class="s2">"iframe"</span>: null, <span class="s2">"mixtapeMetadata"</span>: null<span class="o">}</span>,
<span class="o">{</span><span class="s2">"id"</span>: <span class="s2">"f30dc1c4fe6c_20"</span>, <span class="s2">"name"</span>: <span class="s2">"f2e8"</span>, <span class="s2">"type"</span>: <span class="s2">"BQ"</span>, <span class="s2">"href"</span>: null, <span class="s2">"layout"</span>: null, <span class="s2">"metadata"</span>: null, <span class="s2">"text"</span>: <span class="s2">"This webhook endpoint receives HTTP POST requests from App Store Connect.</span><span class="se">\n</span><span class="s2">このWebhookエンドポイントはApp Store ConnectからのHTTP POSTリクエストを受け取ります。"</span>, <span class="s2">"hasDropCap"</span>: null, <span class="s2">"dropCapImage"</span>: null, <span class="s2">"markups"</span>: <span class="o">[{</span><span class="s2">"type"</span>: <span class="s2">"EM"</span>, <span class="s2">"start"</span>: 0, <span class="s2">"end"</span>: 126, <span class="s2">"href"</span>: null, <span class="s2">"anchorType"</span>: null, <span class="s2">"userId"</span>: null, <span class="s2">"linkMetadata"</span>: null, <span class="s2">"__typename"</span>: <span class="s2">"Markup"</span><span class="o">}]</span>, <span class="s2">"__typename"</span>: <span class="s2">"Paragraph"</span>, <span class="s2">"codeBlockMetadata"</span>: null, <span class="s2">"iframe"</span>: null, <span class="s2">"mixtapeMetadata"</span>: null<span class="o">}</span>,
<span class="o">{</span><span class="s2">"id"</span>: <span class="s2">"f30dc1c4fe6c_21"</span>, <span class="s2">"name"</span>: <span class="s2">"1725"</span>, <span class="s2">"type"</span>: <span class="s2">"BQ"</span>, <span class="s2">"href"</span>: null, <span class="s2">"layout"</span>: null, <span class="s2">"metadata"</span>: null, <span class="s2">"text"</span>: <span class="s2">"The POST requests describe important events about your app.</span><span class="se">\n</span><span class="s2">これらのPOSTリクエストはあなたのアプリに関する重要なイベントを説明します。"</span>, <span class="s2">"hasDropCap"</span>: null, <span class="s2">"dropCapImage"</span>: null, <span class="s2">"markups"</span>: <span class="o">[{</span><span class="s2">"type"</span>: <span class="s2">"EM"</span>, <span class="s2">"start"</span>: 0, <span class="s2">"end"</span>: 89, <span class="s2">"href"</span>: null, <span class="s2">"anchorType"</span>: null, <span class="s2">"userId"</span>: null, <span class="s2">"linkMetadata"</span>: null, <span class="s2">"__typename"</span>: <span class="s2">"Markup"</span><span class="o">}]</span>, <span class="s2">"__typename"</span>: <span class="s2">"Paragraph"</span>, <span class="s2">"codeBlockMetadata"</span>: null, <span class="s2">"iframe"</span>: null, <span class="s2">"mixtapeMetadata"</span>: null<span class="o">}</span>,
<span class="o">{</span><span class="s2">"id"</span>: <span class="s2">"f30dc1c4fe6c_22"</span>, <span class="s2">"name"</span>: <span class="s2">"3e9d"</span>, <span class="s2">"type"</span>: <span class="s2">"BQ"</span>, <span class="s2">"href"</span>: null, <span class="s2">"layout"</span>: null, <span class="s2">"metadata"</span>: null, <span class="s2">"text"</span>: <span class="s2">"Use the webhooks notifications endpoint to configure the notifications for events happening to your apps.</span><span class="se">\n</span><span class="s2">Webhook通知エンドポイントを使って、アプリで発生するイベントの通知設定ができます。"</span>, <span class="s2">"hasDropCap"</span>: null, <span class="s2">"dropCapImage"</span>: null, <span class="s2">"markups"</span>: <span class="o">[{</span><span class="s2">"type"</span>: <span class="s2">"EM"</span>, <span class="s2">"start"</span>: 0, <span class="s2">"end"</span>: 151, <span class="s2">"href"</span>: null, <span class="s2">"anchorType"</span>: null, <span class="s2">"userId"</span>: null, <span class="s2">"linkMetadata"</span>: null, <span class="s2">"__typename"</span>: <span class="s2">"Markup"</span><span class="o">}]</span>, <span class="s2">"__typename"</span>: <span class="s2">"Paragraph"</span>, <span class="s2">"codeBlockMetadata"</span>: null, <span class="s2">"iframe"</span>: null, <span class="s2">"mixtapeMetadata"</span>: null<span class="o">}</span>,
そしてstart, endに従ってMarkdownをレンダリングしますが、現在はアルゴリズムがないためループで埋める方法を使っています。
</code></pre></div></div>

<h4 id="2-方案確定後研究生-agent-開始研究---初版rfcを作成開始">2. 方案確定後研究生 Agent 開始研究 -&gt; 初版RFCを作成開始</h4>

<h4 id="3-教授エージェントがレビュー開始---rejected">3. 教授エージェントがレビュー開始 -&gt; REJECTED</h4>

<p>主な理由は、教授が RFC にまだ <strong>6つの必須修正事項（MUST-FIX）</strong> があると考えており、これらは修正しなければ通過できない仕様／アルゴリズムの正確性の問題だからです。</p>

<p><img src="/assets/f7bec8f79c08/1*wJuWgRv0aQqpDWkjORt1nw.webp" alt="" loading="lazy" decoding="async" width="967" height="469" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjciIGhlaWdodD0iNDY5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/f7bec8f79c08/1*wJuWgRv0aQqpDWkjORt1nw.png" /></p>

<h4 id="4-研究生エージェントが再調査修正--第二版rfcを作成">4. 研究生エージェントが再調査・修正 → 第二版RFCを作成</h4>

<h4 id="5-教授エージェントによる再レビュー---承認済み">5. 教授エージェントによる再レビュー -&gt; 承認済み</h4>

<h4 id="6-完了">6. 完了</h4>

<ul>
  <li>
    <p>所要時間：約 1 時間 30 分</p>
  </li>
  <li>
    <p>消費したトークン：178K（Claude Code Max 5時間利用可能枠の約30%）</p>
  </li>
</ul>

<h3 id="rangeable-rfc">Rangeable RFC</h3>

<p><a href="https://github.com/ZhgChgLi/RangeableRFC/blob/main/RFC.md" target="_blank"><img src="https://opengraph.githubassets.com/c1bbe414aeed52b95e22e3420b934b9cc8d1b4fc8feb04da559f7d9b381f7f0f/ZhgChgLi/RangeableRFC" alt="" /></a></p>

<h4 id="tldr">TL;DR</h4>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">Rangeable&lt;Element&gt;</code> <em>は「要素がどの整数閉区間内で有効か」を管理する汎用データ構造です。同じ要素の重複または隣接する区間を自動的にマージし、特定のインデックスでどの要素がアクティブかを検索したり、ある範囲内のオープン／クローズのトランジションイベントを出力したりできます。元々は Medium Markdown のマークアップレンダリング問題、例えばある文字に <code class="language-plaintext highlighter-rouge">STRONG</code>、<code class="language-plaintext highlighter-rouge">EM</code>、<code class="language-plaintext highlighter-rouge">LINK</code> のどのスタイルが同時に適用されているかを判定するために作られましたが、同様に <strong>カレンダー、ゲーム状態、ゲノムアノテーション、AVPlayer のバイトレンジキャッシュなどの場面にも適用可能です</strong>。コアバリューは「区間のマージ、アクティブセットの検索、境界イベントの生成」を決定的でクロスランゲージに一貫した仕様に抽象化し、Ruby や Swift での実装に適した形にしたことです。</em></p>
</blockquote>

<blockquote>
  <p>以下の RFC の詳細は、特に興味がなければ飛ばしても構いません。ここも AI による要約翻訳を使っています。</p>
</blockquote>

<p><code class="language-plaintext highlighter-rouge">Rangeable&lt;Element&gt;</code> は「<strong>要素を複数の整数閉区間に対応させ、ある位置でどの要素が有効かを高速に検索できる</strong>」汎用データ構造です。</p>

<p>それが解決するのは単純な <code class="language-plaintext highlighter-rouge">Range</code> の問題ではなく、多くの <code class="language-plaintext highlighter-rouge">(要素, start, end)</code> を与えられたときに、以下を実現できることです：</p>

<ol>
  <li>
    <p>ある要素が含まれる結合後の区間を調べる</p>
  </li>
  <li>
    <p>あるインデックスでどの要素が有効かを調べる</p>
  </li>
  <li>
    <p>ある範囲内にどのような open / close の境界イベントがあるか調べる</p>
  </li>
</ol>

<p>RFC は <code class="language-plaintext highlighter-rouge">Rangeable</code> を言語に依存しない、ジェネリックで整数座標の閉区間セットコンテナとして明確に定義しています。要素はハッシュ可能で、比較は値の等価性に基づきます。<code class="language-plaintext highlighter-rouge">getRange</code>、<code class="language-plaintext highlighter-rouge">r[i].objs</code>、<code class="language-plaintext highlighter-rouge">transitions</code> の3種類のクエリをサポートしています。</p>

<h4 id="主な動機">主な動機</h4>

<p>この RFC は <code class="language-plaintext highlighter-rouge">ZMediumToMarkdown</code> の Medium マークアップレンダリング問題に起因しています。</p>

<p>Medium の段落内にはこのようなマークアップがあります：</p>

<div class="language-makefile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">STRONG</span><span class="o">:</span> <span class="nf">[2</span><span class="p">,</span><span class="nf"> 5]</span>
<span class="nl">STRONG</span><span class="o">:</span> <span class="nf">[3</span><span class="p">,</span><span class="nf"> 7]</span>
<span class="nl">EM</span><span class="o">:</span>     <span class="nf">[4</span><span class="p">,</span><span class="nf"> 10]</span>
</code></pre></div></div>

<p>現在のレンダリングでは、各文字ごとにどのタグがアクティブか（例えば bold、italic、link、code など）を逐一スキャンして判定しています。RFC では、従来の方法が markups を <code class="language-plaintext highlighter-rouge">TagChar</code> に変換し、<code class="language-plaintext highlighter-rouge">startIndex</code> によってソートした後、各文字に対して全てのタグを線形に走査するため、最悪で <code class="language-plaintext highlighter-rouge">O(L · m)</code> になると述べています。<code class="language-plaintext highlighter-rouge">Rangeable</code> はこれを汎用コンテナとして抽象化し、レンダラーは単に markups を挿入し、あとは <code class="language-plaintext highlighter-rouge">r[i].objs</code> や <code class="language-plaintext highlighter-rouge">transitions</code> を使ってクエリするだけで済むようにしたいと考えています。</p>

<p>RFC はこの問題を他のシーンにも拡張しています。例えば：</p>

<p><img src="/assets/f7bec8f79c08/1*AWs90nwJGkKee9iEzLwexQ.webp" alt="" loading="lazy" decoding="async" width="611" height="275" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MTEiIGhlaWdodD0iMjc1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/f7bec8f79c08/1*AWs90nwJGkKee9iEzLwexQ.png" /></p>

<p>RFC は共通の問題として次のことを明確に指摘しています：多くの <code class="language-plaintext highlighter-rouge">(eᵢ, lᵢ, hᵢ)</code> が与えられたとき、ある位置 <code class="language-plaintext highlighter-rouge">i</code> を検索すると、<code class="language-plaintext highlighter-rouge">l ≤ i ≤ h</code> を満たすすべての要素を返す必要があります。</p>

<h4 id="コアコンセプト翻訳">コアコンセプト翻訳</h4>

<h4 id="1-rangeableelement">1. <code class="language-plaintext highlighter-rouge">Rangeable&lt;Element&gt;</code></h4>

<p>こう考えてもいいです：</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">Element</span> <span class="nt">-</span><span class="o">&gt;</span> <span class="o">[</span><span class="nt">ClosedRange</span><span class="o">&lt;</span><span class="nt">Int</span><span class="o">&gt;]</span>
</code></pre></div></div>

<p>しかし、それは普通の Dictionary ではありません。なぜなら、次のことを行うからです：</p>

<ol>
  <li>
    <p>同じ要素の重複する区間を自動的にマージする</p>
  </li>
  <li>
    <p>隣接する区間の自動マージ</p>
  </li>
  <li>
    <p>要素の最初の挿入順序を保持する</p>
  </li>
  <li>
    <p>あるインデックス上でアクティブな要素を高速に検索するサポート</p>
  </li>
  <li>
    <p>オープン／クローズのトランジションイベントの出力をサポート</p>
  </li>
</ol>

<p>例えば：</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">insert</span><span class="o">(</span><span class="nt">STRONG</span><span class="o">,</span> <span class="nt">2</span><span class="o">,</span> <span class="nt">5</span><span class="o">)</span>
<span class="nt">insert</span><span class="o">(</span><span class="nt">STRONG</span><span class="o">,</span> <span class="nt">3</span><span class="o">,</span> <span class="nt">7</span><span class="o">)</span>
</code></pre></div></div>

<p>最後はこうなります：</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">STRONG</span> <span class="nt">-</span><span class="o">&gt;</span> <span class="o">[(</span><span class="err">2</span><span class="o">,</span> <span class="err">7</span><span class="o">)]</span>
</code></pre></div></div>

<p>なぜなら <code class="language-plaintext highlighter-rouge">[2,5]</code> と <code class="language-plaintext highlighter-rouge">[3,7]</code> が重なっているからです。</p>

<h4 id="apiのポイント">APIのポイント</h4>

<p>RFC 定義の主な API は以下の通りです。</p>

<h4 id="inserte-start-end"><code class="language-plaintext highlighter-rouge">insert(e, start, end)</code></h4>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">insert</span><span class="p">(</span><span class="n">e</span><span class="p">:</span> <span class="n">Element</span><span class="p">,</span> <span class="k">start</span><span class="p">:</span> <span class="nb">Int</span><span class="p">,</span> <span class="k">end</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span>
</code></pre></div></div>

<p>効果は：</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">R</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o">=</span> <span class="n">canonicalize</span><span class="p">(</span><span class="n">R</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="err">∪</span> <span class="p">[</span><span class="k">start</span><span class="p">,</span> <span class="k">end</span><span class="p">])</span>
</code></pre></div></div>

<p>つまり、新しい区間を要素 <code class="language-plaintext highlighter-rouge">e</code> の既存の区間集合に追加し、canonicalize を行う：重複または隣接するすべての区間をマージしてソートする。<code class="language-plaintext highlighter-rouge">start &gt; end</code> の場合は <code class="language-plaintext highlighter-rouge">InvalidIntervalError</code> を投げる必要がある；同じ内容を重複して挿入することは冪等であり、結果を変更せず、バージョンも増やしてはいけない。</p>

<h4 id="riobjs--activeatindex"><code class="language-plaintext highlighter-rouge">r[i].objs</code> / <code class="language-plaintext highlighter-rouge">activeAt(index:)</code></h4>

<pre><code class="language-less">r[i] -&gt; スロット
r.activeAt(index: i) -&gt; スロット
</code></pre>

<p>ある index 上でアクティブな要素を返す。</p>

<p>例えば：</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">insert</span><span class="o">(</span><span class="nt">Strong</span><span class="o">,</span> <span class="nt">2</span><span class="o">,</span> <span class="nt">5</span><span class="o">)</span>
<span class="nt">insert</span><span class="o">(</span><span class="nt">Italic</span><span class="o">,</span> <span class="nt">3</span><span class="o">,</span> <span class="nt">7</span><span class="o">)</span>
</code></pre></div></div>

<p>検索：</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">r</span><span class="o">[</span><span class="err">3</span><span class="o">]</span><span class="nc">.objs</span>
</code></pre></div></div>

<p>結果は：</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Strong</span><span class="p">,</span> <span class="n">Italic</span><span class="p">]</span>
</code></pre></div></div>

<p>クエリの複雑度の目標は：</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">O</span><span class="o">(</span><span class="nt">log</span> <span class="nt">M</span> <span class="o">+</span> <span class="nt">r</span><span class="o">)</span>
</code></pre></div></div>

<p>ここで <code class="language-plaintext highlighter-rouge">M</code> はすべての要素をマージした後のインターバルの総数、<code class="language-plaintext highlighter-rouge">r</code> はその位置で実際に返される要素の数です。</p>

<h4 id="getrangeof"><code class="language-plaintext highlighter-rouge">getRange(of:)</code></h4>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">getRange</span><span class="o">(</span><span class="nt">of</span> <span class="nt">e</span><span class="o">)</span> <span class="nt">-</span><span class="o">&gt;</span> <span class="o">[(</span><span class="nt">Int</span><span class="o">,</span> <span class="nt">Int</span><span class="o">)]</span>
</code></pre></div></div>

<p>ある要素の現在のマージ後の正規化範囲を返す。</p>

<p>例えば：</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">insert</span><span class="o">(</span><span class="nt">Strong</span><span class="o">,</span> <span class="nt">2</span><span class="o">,</span> <span class="nt">4</span><span class="o">)</span>
<span class="nt">insert</span><span class="o">(</span><span class="nt">Strong</span><span class="o">,</span> <span class="nt">5</span><span class="o">,</span> <span class="nt">7</span><span class="o">)</span>
</code></pre></div></div>

<p>なぜなら <code class="language-plaintext highlighter-rouge">[2,4]</code> と <code class="language-plaintext highlighter-rouge">[5,7]</code> は整数座標上で隣接しているため、結果は：</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[(</span><span class="err">2</span><span class="o">,</span> <span class="err">7</span><span class="o">)]</span>
</code></pre></div></div>

<p>RFC は、返される intervals が必ずソートされており、重複せず、隣接していないことを明確に要求しています。</p>

<h4 id="transitionsover"><code class="language-plaintext highlighter-rouge">transitions(over:)</code></h4>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">transitions</span><span class="err">(</span><span class="na">over</span><span class="p">:</span> <span class="n">ClosedRange</span><span class="o">&lt;</span><span class="n">Int</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">TransitionEvent</span><span class="p">]</span>
</code></pre></div></div>

<p>範囲内の open / close 境界イベントを返します。</p>

<p>例えば：</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">insert</span><span class="o">(</span><span class="nt">Strong</span><span class="o">,</span> <span class="nt">2</span><span class="o">,</span> <span class="nt">5</span><span class="o">)</span>
<span class="nt">insert</span><span class="o">(</span><span class="nt">Italic</span><span class="o">,</span> <span class="nt">3</span><span class="o">,</span> <span class="nt">7</span><span class="o">)</span>
</code></pre></div></div>

<p>すると transitions は以下のようになります：</p>

<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span>
  <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">open</span><span class="p">,</span>  <span class="n">Strong</span><span class="p">),</span>  <span class="c1">-- Strongタグを開く</span>
  <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">open</span><span class="p">,</span>  <span class="n">Italic</span><span class="p">),</span>  <span class="c1">-- Italicタグを開く</span>
  <span class="p">(</span><span class="mi">6</span><span class="p">,</span> <span class="n">close</span><span class="p">,</span> <span class="n">Strong</span><span class="p">),</span>  <span class="c1">-- Strongタグを閉じる</span>
  <span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="n">close</span><span class="p">,</span> <span class="n">Italic</span><span class="p">)</span>   <span class="c1">-- Italicタグを閉じる</span>
<span class="p">]</span>
</code></pre></div></div>

<p>注意すべきは close イベントの位置が <code class="language-plaintext highlighter-rouge">hi + 1</code> であることです。外部の意味としては閉区間 <code class="language-plaintext highlighter-rouge">[lo, hi]</code> ですが、sweep-line 内部では「最初にアクティブでなくなる位置」を close 座標として使用します。RFC では <code class="language-plaintext highlighter-rouge">transitions(over: lo..hi)</code> が <code class="language-plaintext highlighter-rouge">hi + 1</code> の close イベントを含むと明確に記載されており、右端の処理を容易にしています。</p>

<h4 id="区間の意味">区間の意味</h4>

<h4 id="1-end-は包含されます">1. <code class="language-plaintext highlighter-rouge">end</code> は包含されます</h4>

<p>この RFC は非常に明確です：<code class="language-plaintext highlighter-rouge">insert(e, start: a, end: b)</code> は閉区間 <code class="language-plaintext highlighter-rouge">[a, b]</code> を表し、<code class="language-plaintext highlighter-rouge">b</code> 自体もアクティブな範囲に含まれます。</p>

<p>つまり：</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">insert</span><span class="o">(</span><span class="nt">Strong</span><span class="o">,</span> <span class="nt">2</span><span class="o">,</span> <span class="nt">5</span><span class="o">)</span>
</code></pre></div></div>

<p>代表：</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span> <span class="nx">はすべてアクティブ</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">[2, 5)</code> ではありません。</p>

<p>RFC が inclusive を選択した理由は以下の通りです：</p>

<ol>
  <li>
    <p>Medium マークアップ / ZMediumToMarkdown に適した履歴データモデル</p>
  </li>
  <li>
    <p>「この文字がアクティブかどうか」という人間の直感に合っている</p>
  </li>
  <li>
    <p>整数の隣接マージは <code class="language-plaintext highlighter-rouge">hi + 1 == lo</code> と表現できます。</p>
  </li>
  <li>
    <p>単一区間 <code class="language-plaintext highlighter-rouge">[k, k]</code> は有効な位置を自然に表現できます</p>
  </li>
</ol>

<h4 id="2-隣接する区間は結合する">2. 隣接する区間は結合する</h4>

<p>整数座標上で：</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="m">2</span><span class="p">,</span> <span class="m">4</span><span class="p">]</span> <span class="p">+</span> <span class="p">[</span><span class="m">5</span><span class="p">,</span> <span class="m">7</span><span class="p">]</span> <span class="p">=&gt;</span> <span class="p">[</span><span class="m">2</span><span class="p">,</span> <span class="m">7</span><span class="p">]</span>
</code></pre></div></div>

<p>4 と 5 の間に「非アクティブ」を表す整数位置がないため、RFC では同じ要素の隣接する整数区間を必ず結合する必要があります。</p>

<p>しかし：</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="m">2</span><span class="p">,</span> <span class="m">4</span><span class="p">]</span> <span class="p">+</span> <span class="p">[</span><span class="m">6</span><span class="p">,</span> <span class="m">7</span><span class="p">]</span> <span class="p">=&gt;</span> <span class="p">[(</span><span class="m">2</span><span class="p">,</span> <span class="m">4</span><span class="p">),</span> <span class="p">(</span><span class="m">6</span><span class="p">,</span> <span class="m">7</span><span class="p">)]</span>
</code></pre></div></div>

<p>中間に <code class="language-plaintext highlighter-rouge">5</code> のギャップがあるためです。</p>

<h4 id="3-start--end-は有効なシングルトン区間です">3. <code class="language-plaintext highlighter-rouge">start == end</code> は有効なシングルトン区間です</h4>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">insert</span><span class="o">(</span><span class="nt">e</span><span class="o">,</span> <span class="nt">5</span><span class="o">,</span> <span class="nt">5</span><span class="o">)</span>
</code></pre></div></div>

<p>代表インデックス <code class="language-plaintext highlighter-rouge">5</code> のみがアクティブです。RFCではこれが有効かつ空でない区間であることを要求しています。</p>

<h4 id="4-start--end-は必ずエラーを投げる必要がある">4. <code class="language-plaintext highlighter-rouge">start &gt; end</code> は必ずエラーを投げる必要がある</h4>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">insert</span><span class="o">(</span><span class="nt">e</span><span class="o">,</span> <span class="nt">10</span><span class="o">,</span> <span class="nt">5</span><span class="o">)</span>
</code></pre></div></div>

<p>自動的に <code class="language-plaintext highlighter-rouge">[5,10]</code> に反転することも、サイレントに正規化することもできません。RFC では <code class="language-plaintext highlighter-rouge">InvalidIntervalError</code> を必ずスローし、かつコンテナの状態を変更してはいけません。</p>

<h4 id="element-equality-の意味">Element equality の意味</h4>

<p><code class="language-plaintext highlighter-rouge">Rangeable</code> は、2つの要素が同じ要素かどうかを判定する際に、言語ネイティブの値の等価性を使用します。</p>

<p>Ruby：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>eql? + <span class="nb">hash</span>
</code></pre></div></div>

<p>Swift：</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">Hashable</span> <span class="o">/</span> <span class="nx">Equatable</span>
</code></pre></div></div>

<p>なので：</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">Link</span><span class="o">(</span><span class="s2">"a"</span><span class="o">)</span> <span class="err">と</span> <span class="nt">Link</span><span class="o">(</span><span class="s2">"a"</span><span class="o">)</span> <span class="err">は同じ要素と見なされ、区間が結合されます</span>
<span class="nt">Link</span><span class="o">(</span><span class="s2">"a"</span><span class="o">)</span> <span class="err">と</span> <span class="nt">Link</span><span class="o">(</span><span class="s2">"b"</span><span class="o">)</span> <span class="err">は異なる要素であり、結合されません</span>
<span class="nt">Strong</span><span class="o">()</span> <span class="err">と</span> <span class="nt">Strong</span><span class="o">()</span> <span class="err">は</span> <span class="nt">equality</span> <span class="err">が等しい場合、結合されます</span>
</code></pre></div></div>

<p>RFC は、等価性が反射律、対称律、推移律、およびハッシュの一貫性を満たす必要があり、要素が挿入された後に外部からの変更によってハッシュや等価性が破壊されてはならないと要求しています。</p>

<h4 id="ソートルール">ソートルール</h4>

<p>これは RFC の非常に重要な部分です。</p>

<h4 id="アクティブセットのソート">アクティブセットのソート</h4>

<p><code class="language-plaintext highlighter-rouge">r[i].objs</code> の順序はハッシュでもアルファベット順でもレンジの長さでもなく、以下の通りです：</p>

<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- 要素が初めて挿入された順序</span>
</code></pre></div></div>

<p>例えば：</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">insert</span><span class="o">(</span><span class="nt">Strong</span><span class="o">,</span> <span class="nt">1</span><span class="o">,</span> <span class="nt">10</span><span class="o">)</span>
<span class="nt">insert</span><span class="o">(</span><span class="nt">Italic</span><span class="o">,</span> <span class="nt">1</span><span class="o">,</span> <span class="nt">10</span><span class="o">)</span>
<span class="nt">insert</span><span class="o">(</span><span class="nt">Code</span><span class="o">,</span> <span class="nt">1</span><span class="o">,</span> <span class="nt">10</span><span class="o">)</span>
</code></pre></div></div>

<p>則：</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">r</span><span class="p">[</span><span class="mi">5</span><span class="p">].</span><span class="nx">objs</span> <span class="o">==</span> <span class="p">[</span><span class="nx">Strong</span><span class="p">,</span> <span class="nx">Italic</span><span class="p">,</span> <span class="nx">Code</span><span class="p">]</span>
</code></pre></div></div>

<p>RFC は、これを行う理由として、決定論的で言語間の一貫性があり、Markdown のネストに適合していることを挙げています：早く出現するスタイルほど通常は外側になります。</p>

<h4 id="マージは挿入順序を変更しません">マージは挿入順序を変更しません</h4>

<p>例えば：</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">insert</span><span class="o">(</span><span class="nt">Strong</span><span class="o">,</span> <span class="nt">1</span><span class="o">,</span> <span class="nt">5</span><span class="o">)</span>   <span class="o">//</span> <span class="nt">Strong</span> <span class="err">の順序</span> <span class="o">=</span> <span class="nt">1</span>
<span class="nt">insert</span><span class="o">(</span><span class="nt">Italic</span><span class="o">,</span> <span class="nt">3</span><span class="o">,</span> <span class="nt">7</span><span class="o">)</span>   <span class="o">//</span> <span class="nt">Italic</span> <span class="err">の順序</span> <span class="o">=</span> <span class="nt">2</span>
<span class="nt">insert</span><span class="o">(</span><span class="nt">Strong</span><span class="o">,</span> <span class="nt">4</span><span class="o">,</span> <span class="nt">8</span><span class="o">)</span>   <span class="o">//</span> <span class="nt">Strong</span> <span class="err">の範囲は</span> <span class="o">[</span><span class="nt">1</span><span class="o">,</span><span class="nt">8</span><span class="o">]</span> <span class="err">にマージされますが、順序は</span> <span class="nt">1</span> <span class="err">のままです</span>
</code></pre></div></div>

<p>検索：</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">r</span><span class="o">[</span><span class="err">6</span><span class="o">]</span><span class="nc">.objs</span>
</code></pre></div></div>

<p>結果は：</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Strong</span><span class="p">,</span> <span class="n">Italic</span><span class="p">]</span>
</code></pre></div></div>

<p>Strong は3番目に index 6 まで拡張されましたが、その first-insert order は Italic よりも早いです。RFC はこのケースで「要素が初めて現れた順序」こそがソートの基準であることを明確にしています。</p>

<h4 id="transitions-の並び替え">Transitions の並び替え</h4>

<p>同じ座標上で：</p>

<ol>
  <li>
    <p><code class="language-plaintext highlighter-rouge">.open</code> は <code class="language-plaintext highlighter-rouge">.close</code> より先に来ます</p>
  </li>
  <li>
    <p>複数の <code class="language-plaintext highlighter-rouge">.open</code> ：挿入順で昇順</p>
  </li>
  <li>
    <p>複数の <code class="language-plaintext highlighter-rouge">.close</code> ：挿入順で降順、つまり LIFO</p>
  </li>
</ol>

<p>このようにすれば Markdown のスタック規律に適合します：</p>

<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">**</span> <span class="err">開く</span>
<span class="n">_</span> <span class="err">開く</span>
<span class="n">_</span> <span class="err">閉じる</span>
<span class="o">**</span> <span class="err">閉じる</span>
</code></pre></div></div>

<p>RFC は、このタイブレークルールを明確に定義しており、Ruby と Swift のハッシュ順序の不一致による言語間の出力差異を防いでいます。</p>

<h4 id="内部データ構造">内部データ構造</h4>

<p>RFC のコア設計の選択は次のとおりです：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Map&lt;Element, SortedList&lt;Interval&gt;&gt;
+ 挿入順序
+ 遅延境界イベントインデックス
+ バージョンカウンター
</code></pre></div></div>

<h4 id="1-要素ごとのソートされた非重複リスト">1. 要素ごとのソートされた非重複リスト</h4>

<p>各要素にはそれぞれ独自のインターバルリストがあります：</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">intervals</span><span class="p">:</span> <span class="kt">Map</span><span class="o">&lt;</span><span class="kt">Element</span><span class="p">,</span> <span class="kt">SortedList</span><span class="o">&lt;</span><span class="kt">Interval</span><span class="o">&gt;&gt;</span>
</code></pre></div></div>

<p>そして、canonical form を維持しなければなりません：</p>

<ol>
  <li>
    <p><code class="language-plaintext highlighter-rouge">lo</code> による昇順ソート</p>
  </li>
  <li>
    <p>お互いに重ならない</p>
  </li>
  <li>
    <p>隣接していない</p>
  </li>
  <li>
    <p>各区間は常に <code class="language-plaintext highlighter-rouge">lo &lt;= hi</code> を満たす</p>
  </li>
</ol>

<p>RFC ではこれを I1 不変条件と呼びます。</p>

<h4 id="2-レイジー境界イベントインデックス">2. レイジー境界イベントインデックス</h4>

<p><code class="language-plaintext highlighter-rouge">Rangeable</code> は毎回 insert のたびに検索インデックスを再構築するのではなく、最初の query 時に初めて構築します。</p>

<div class="language-makefile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">version</span><span class="o">:</span> <span class="nf">Int</span>
<span class="nl">event_index</span><span class="o">:</span> <span class="nf">EventIndex?</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">event_index</code> には以下が含まれます：</p>

<pre><code class="language-vbnet">events: SortedArray&lt;Event&gt;
segments: SortedArray&lt;Segment&gt;
version: Int
</code></pre>

<p>この設計は「一度構築してから密にクエリを行う」ワークロードに対応するためのものです：大量の挿入が完了した後、各位置を集中的に検索します。RFCでは、ビルドフェーズでインデックスを何度も再構築する必要がないため、lazy indexがこのパターンに適していると明確に述べています。クエリフェーズでは一度だけ <code class="language-plaintext highlighter-rouge">O(M log M)</code> のコストがかかります。</p>

<h4 id="アルゴリズムのポイント">アルゴリズムのポイント</h4>

<h4 id="insert-のコアプロセス"><code class="language-plaintext highlighter-rouge">insert</code> のコアプロセス</h4>

<p>RFC の擬似コードは大まかに以下の通りです：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function </span>insert<span class="o">(</span>r, e, start, end<span class="o">)</span>:
  <span class="k">if </span>start <span class="o">&gt;</span> end:
    raise InvalidIntervalError

  e_frozen <span class="o">=</span> freeze_for_insert<span class="o">(</span>e<span class="o">)</span>

  <span class="k">if </span>e not <span class="k">in </span>intervals:
    intervals[e] <span class="o">=</span> <span class="o">[]</span>
    insertion_order.append<span class="o">(</span>e<span class="o">)</span>
    ord[e] <span class="o">=</span> insertion_order.length

  list <span class="o">=</span> intervals[e]
  lo <span class="o">=</span> start
  hi <span class="o">=</span> end

  <span class="c"># [lo, hi] と重複または隣接する最初の interval を見つける</span>

  <span class="k">while </span>interval が <span class="o">[</span>lo, hi] と重複または隣接する:
    lo <span class="o">=</span> min<span class="o">(</span>lo, interval.lo<span class="o">)</span>
    hi <span class="o">=</span> max<span class="o">(</span>hi, interval.hi<span class="o">)</span>
    <span class="c"># 古い interval を削除する</span>

  <span class="c"># マージした新しい [lo, hi] を挿入する</span>

  <span class="k">if </span>実際に変更があった場合:
    version +<span class="o">=</span> 1
    event_index <span class="o">=</span> nil
</code></pre></div></div>

<p>特に RFC では、<code class="language-plaintext highlighter-rouge">lo - 1</code> を使って判定してはいけないと注意しています。<code class="language-plaintext highlighter-rouge">lo == Int.min</code> の場合にアンダーフローが発生するためです。代わりに <code class="language-plaintext highlighter-rouge">hi + 1 &gt;= lo</code> または同等の successor モデルを使うべきです。</p>

<h4 id="複雑さ">複雑さ</h4>

<p>RFC が選択した参考構造は：</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">要素ごとにソ</span><span class="n">ー</span><span class="err">トされた非重複リスト</span> <span class="p">+</span> <span class="err">遅延イベントインデックス</span>
</code></pre></div></div>

<p>複雑度はおおよそ以下の通りです：</p>

<p><img src="/assets/f7bec8f79c08/1*5HKeVhHLMRIWnuJJmmGTbQ.webp" alt="" loading="lazy" decoding="async" width="396" height="197" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzOTYiIGhlaWdodD0iMTk3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/f7bec8f79c08/1*5HKeVhHLMRIWnuJJmmGTbQ.png" /></p>

<p>その中で：</p>

<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">m_e</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">ある element 自身のマージされた区間の数</span>
<span class="py">k</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">今回の挿入で吸収／合併された古い区間の数</span>
<span class="py">M</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">すべての element のマージされた区間の総数</span>
<span class="py">r</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">クエリ位置で実際にアクティブな element の数</span>
</code></pre></div></div>

<p>RFC はまた、同じ位置に実際に <code class="language-plaintext highlighter-rouge">m</code> 個の要素がアクティブであれば、出力自体が <code class="language-plaintext highlighter-rouge">Ω(m)</code> を必要とするため、<code class="language-plaintext highlighter-rouge">O(log M + m)</code> はすでに出力感度のある合理的な境界であると指摘しています。</p>

<h4 id="なぜ-interval-tree--segment-tree--roaring-bitmap-を使わないのか">なぜ Interval Tree / Segment Tree / Roaring Bitmap を使わないのか？</h4>

<p>RFC には代替案を比較したセクションがあり、最終的に <code class="language-plaintext highlighter-rouge">(a) Per-element sorted disjoint list + lazy event index</code> を選択しました。</p>

<p>重要なポイントは以下の通りです：</p>

<p><img src="/assets/f7bec8f79c08/1*psrNFxHTKrwba92dA0rOLw.webp" alt="" loading="lazy" decoding="async" width="891" height="275" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4OTEiIGhlaWdodD0iMjc1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/f7bec8f79c08/1*psrNFxHTKrwba92dA0rOLw.png" /></p>

<p>RFC 総括でメイン構造を選んだ3つの理由：</p>

<ol>
  <li>
    <p>per-element merge の意味が自然で、<code class="language-plaintext highlighter-rouge">getRange</code> は直接 <code class="language-plaintext highlighter-rouge">R(e)</code> を返すことができます</p>
  </li>
  <li>
    <p>決定論的で、クロスランゲージで再現可能です</p>
  </li>
  <li>
    <p>lazy index は一度構築してからクエリするワークロードに非常に適しています。</p>
  </li>
</ol>

<h4 id="v1-に含まれていない機能">v1 に含まれていない機能</h4>

<p>RFC はっきりと v1 で行わないことを列挙：</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">remove</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="k">start</span><span class="p">,</span> <span class="k">end</span><span class="p">)</span>
<span class="n">remove</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="n">clear</span>
<span class="k">union</span> <span class="o">/</span> <span class="k">intersect</span> <span class="o">/</span> <span class="n">difference</span>
<span class="n">persistent</span> <span class="k">immutable</span> <span class="n">snapshot</span>
<span class="err">浮動小数点座標</span>
<span class="err">多次元矩形スタッキング</span>
<span class="n">r</span><span class="p">[</span><span class="n">lo</span><span class="p">...</span><span class="n">hi</span><span class="p">].</span><span class="n">objs</span> <span class="err">のような</span> <span class="k">range</span> <span class="n">slot</span> <span class="n">query</span>
</code></pre></div></div>

<p>削除や交差部分もAIに任せて、RFC V2で実装してください。</p>

<h3 id="aiによりrangeable-rfcを基に言語実装を行う">AIにより<a href="https://github.com/ZhgChgLi/RangeableRFC" target="_blank">Rangeable RFC</a>を基に言語実装を行う</h3>

<h4 id="フロー-1">フロー</h4>

<ol>
  <li>
    <p>同様にまず <code class="language-plaintext highlighter-rouge">/plan</code> の Plan Mode を実行し、AI に RFC を詳細に読み込ませて実装を計画させる</p>
  </li>
  <li>
    <p>同様に developer と reviewer に分けて、一方が作成しもう一方がレビューを行い、問題がなくなるまで繰り返します。</p>
  </li>
  <li>
    <p>Readme 使用ドキュメントの作成と GitHub へのプッシュ</p>
  </li>
</ol>

<blockquote>
  <p><em>最も難しい RFC 仕様の研究が完了した後は、AI がこの仕様に従って実装するだけで、ほとんど問題が発生しません。</em></p>
</blockquote>

<h4 id="現在実装されている言語は以下の通りです">現在実装されている言語は以下の通りです。</h4>

<ul>
  <li>
    <p>Ruby 3.2+ <a href="https://github.com/ZhgChgLi/RubyRangeable" target="_blank">github.com/ZhgChgLi/RubyRangeable</a></p>
  </li>
  <li>
    <p>Swift 5.7+ <a href="https://github.com/ZhgChgLi/SwiftRangeable" target="_blank">github.com/ZhgChgLi/SwiftRangeable</a></p>
  </li>
  <li>
    <p>Python 3.10+ <a href="https://github.com/ZhgChgLi/PythonRangeable" target="_blank">github.com/ZhgChgLi/PythonRangeable</a></p>
  </li>
  <li>
    <p>TypeScript / JS (Node 18+) <a href="https://github.com/ZhgChgLi/JSRangeable" target="_blank">github.com/ZhgChgLi/JSRangeable</a></p>
  </li>
  <li>
    <p>Kotlin / JVM 11+ <a href="https://github.com/ZhgChgLi/KotlinRangeable" target="_blank">github.com/ZhgChgLi/KotlinRangeable</a></p>
  </li>
  <li>
    <p>Go 1.22+ <a href="https://github.com/ZhgChgLi/GoRangeable" target="_blank">github.com/ZhgChgLi/GoRangeable</a></p>
  </li>
</ul>

<h3 id="実際に-ai-を活用して設計開発した--rangeable-foundation">実際に AI を活用して設計・開発した — Rangeable Foundation</h3>

<p>すべて準備が整ったら、最初のオープンソースプロジェクト ZMediumToMarkdown のアルゴリズム問題に戻り、AI にこのライブラリを適用して、元の複雑なウォークスルーの方法を取り除き、構造を最適化＋ <strong>適用前後のテスト検証を追加</strong> してください。</p>

<h4 id="zmediumtomarkdown-360"><a href="https://github.com/ZhgChgLi/ZMediumToMarkdown/releases/tag/v3.6.0" target="_blank">ZMediumToMarkdown 3.6.0</a></h4>

<p><strong>パフォーマンス</strong></p>

<ul>
  <li>
    <p>マイクロベンチマーク：マークアップレンダリングのホットパスで5.5倍高速化。</p>
  </li>
  <li>
    <p>実際の Medium 記事でのエンドツーエンド処理：2.23倍高速化<br />
（平均で1段落あたり2073 µs → 930 µs）。</p>
  </li>
</ul>

<h4 id="avplayer-ローカルキャッシュ実装攻略"><a href="https://zhgchg.li/posts/zrealm-dev/avplayer-%E6%9C%AC%E5%9C%B0-cache-%E5%AF%A6%E4%BD%9C%E6%94%BB%E7%95%A5-%E4%BD%BF%E7%94%A8-avassetresourceloaderdelegate-%E7%AF%80%E7%9C%81-ios-%E9%9F%B3%E6%A8%82%E4%B8%B2%E6%B5%81%E6%B5%81%E9%87%8F-6ce488898003/#20260510-updated" target="_blank">AVPlayer ローカルキャッシュ実装攻略</a></h4>

<p>記事内容には SwiftRangeable の適用例も追加されています。</p>

<h3 id="aiに感嘆する">AIに感嘆する</h3>

<p>これまでは AI を使って <a href="/posts/zrealm-開発/claude-design-claude-codeで週末午後に作るオリジナルjekyllブログテーマ-6bf79c5b4dab/">ウェブサイトの再設計</a> や <a href="/posts/zrealm開発/ai-agentでgoogle-apps-script開発を効率化-ゼロから始めずに自動化を実現-35cc65327d28/">個人ダッシュボード</a> 、あるいは仕事上の製品問題の修正などの応用的な問題に取り組んでいましたが、初めてアルゴリズムや基盤データ設計の問題を深く研究し解決するよう依頼しました。</p>

<p>効果は私の想像を超えました。彼が書いたRFCをざっと読んでみましたが、形式も内容も実際の人間が研究して書いたものに劣らず（少なくとも私が書いたものよりは確実に良い）、途中で彼が何をしているか観察すると、Web検索を使って公開されている関連論文や技術文献を調べ、それらを統合して実装の妥当性を評価していました。doer / reviewer に役割を分けた効果も非常に顕著で、doerは実装に偏りがちですが、reviewerはより広く高い視点からdoerの作業に副作用がないか俯瞰的に見ています。最後にRFCが決まった後、AIに基づいて実装を依頼すると、その正確性はほぼ100％でした。</p>

<h4 id="ai-使用の振り返り">AI 使用の振り返り</h4>

<p>ただし、皆さんはAIに取って代わられることを恐れる必要はありません。問題を解決する思考こそが重要であり、このAIはそこまで強くありません。例えば、直接AIにZMediumToMarkdownの最適化を依頼しても、Mediumのシーンや元のコードの書き方にしか集中できないでしょう。<strong>しかし、人間はFoundationとして抽象化し、まずRFCを研究し、最終的に実装することで、より良い結果を得られることを知っています。もちろん、自分たちで行うことも可能ですが時間がかかります。AIはそのプロセスを加速するものであり、取って代わるものではありません。</strong></p>

<p><em><a href="https://medium.com/zrealm-ios-dev/ai-%E4%B8%8D%E5%8F%AA%E6%9C%83%E5%81%9A%E6%87%89%E7%94%A8-%E7%94%A8-ai-%E5%8D%94%E4%BD%9C%E5%AE%8C%E6%88%90%E4%B8%80%E4%BB%BD%E8%B3%87%E6%96%99%E7%B5%90%E6%A7%8B-rfc-%E8%88%87%E5%A4%9A%E8%AA%9E%E8%A8%80%E5%AF%A6%E4%BD%9C-f7bec8f79c08" target="_blank">Post</a> Mediumから変換されたもの by <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>.</em></p>]]></content>
  </entry><entry>
    <title type="html">IQUNIX MG 65/75/96 Pro｜矮軸軽量メカニカルキーボード三モデル比較｜アルミ合金ボディでMac対応</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-life/iqunix-mg-65-75-96-pro-%E7%9F%AE%E8%BB%B8%E8%BB%BD%E9%87%8F%E3%83%A1%E3%82%AB%E3%83%8B%E3%82%AB%E3%83%AB%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E4%B8%89%E3%83%A2%E3%83%87%E3%83%AB%E6%AF%94%E8%BC%83-%E3%82%A2%E3%83%AB%E3%83%9F%E5%90%88%E9%87%91%E3%83%9C%E3%83%87%E3%82%A3%E3%81%A7mac%E5%AF%BE%E5%BF%9C-0d4a5fd2929b/" rel="alternate" type="text/html" title="IQUNIX MG 65/75/96 Pro｜矮軸軽量メカニカルキーボード三モデル比較｜アルミ合金ボディでMac対応" />
    <published>2026-05-09T00:33:11+08:00</published>
    <updated>2026-05-09T00:33:11+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-life/0d4a5fd2929b</id><summary type="html">Macユーザー必見のIQUNIX MG75 Proは、アルミ合金製の高級感と軽快なタイピング感を両立。三つのモデルを比較し、最適な矮軸キーボード選びをサポートします。快適な操作性で作業効率アップを実現。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm Life." /><category term="iqunix" /><category term="タオバオ" /><category term="生活" /><category term="開封レビュー" /><category term="メカニカルキーボード" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/0d4a5fd2929b/1*UYsoPN7LJA8eLwCW3neySg.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-life/iqunix-mg-65-75-96-pro-%E7%9F%AE%E8%BB%B8%E8%BB%BD%E9%87%8F%E3%83%A1%E3%82%AB%E3%83%8B%E3%82%AB%E3%83%AB%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E4%B8%89%E3%83%A2%E3%83%87%E3%83%AB%E6%AF%94%E8%BC%83-%E3%82%A2%E3%83%AB%E3%83%9F%E5%90%88%E9%87%91%E3%83%9C%E3%83%87%E3%82%A3%E3%81%A7mac%E5%AF%BE%E5%BF%9C-0d4a5fd2929b/"><![CDATA[<h3 id="iqunix-mg-657596-pro-低軸軽羽軸三モードアルミ合金ケースメカニカルキーボード-ナイトブラック開封レビュー">IQUNIX MG 65/75/96 Pro 低軸軽羽軸三モードアルミ合金ケースメカニカルキーボード ナイトブラック開封レビュー</h3>

<p>MacOS対応のアルミ合金質感と軽快な操作感のIQUNIX MG75 Pro開封レビュー</p>

<p><img src="/assets/0d4a5fd2929b/1*UYsoPN7LJA8eLwCW3neySg.webp" alt="MG75 Pro 開封体験" loading="lazy" decoding="async" width="1200" height="902" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*UYsoPN7LJA8eLwCW3neySg.png" /></p>

<p><a href="https://iqunix.com/products/iqunix-magi75-96-aluminum-low-profile-mechanical-keyboard?variant=50355797393714" target="_blank">MG75 Pro 開封レビュー</a></p>

<h4 id="はじめに">はじめに</h4>

<p>久しぶりに開封レビューを書きますが、特に珍しいものはありません。最近、ちょうど2年間使っていた中古のメカニカルキーボードが寿命を迎えました（実は水をこぼしてしまったためです）。同僚が自作した高軸のキーボードで、ベースは DUKHARO — VN66、軸はおそらく黄軸か白軸です。</p>

<p><img src="/assets/0d4a5fd2929b/1*tBmCni-mJ0ZPat8Uf7dqfQ.webp" alt="古いキーボード" loading="lazy" decoding="async" width="1200" height="491" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQ5MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*tBmCni-mJ0ZPat8Uf7dqfQ.png" /></p>

<p>古いキーボード</p>

<p>メカニカルキーボードにハマる前は、AppleのMagic Keyboardが一番好きでした。低めの軸のキーボードが好みで、さらにAppleユーザーなので、このモデルがぴったりです。</p>

<p><img src="/assets/0d4a5fd2929b/1*vMEz6OFmApz2ZXj2aeQq5A.webp" alt="Apple マジックキーボード" loading="lazy" decoding="async" width="1200" height="331" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjMzMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*vMEz6OFmApz2ZXj2aeQq5A.jpeg" /></p>

<p>Apple マジックキーボード</p>

<p>しかし、打鍵感はまさに純粋なチョコレートキーボードで、ペタペタしていてフィードバックが全くありません。</p>

<h3 id="iqunix-mg657596-pro-低軸軽羽軸三モードアルミ合金ケースメカニカルキーボード">IQUNIX MG65/75/96 Pro 低軸軽羽軸三モードアルミ合金ケースメカニカルキーボード</h3>

<p><img src="/assets/0d4a5fd2929b/1*5tbfNVtQ2DxnxZNDApzf_A.webp" alt="&lt;https://iqunix.com/products/iqunix-magi75-96-aluminum-low-profile-mechanical-keyboard?variant=50355797590322&gt;" loading="lazy" decoding="async" width="2908" height="1042" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOTA4IiBoZWlnaHQ9IjEwNDIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/0d4a5fd2929b/1*5tbfNVtQ2DxnxZNDApzf_A.png" /></p>

<p><a href="https://iqunix.com/products/iqunix-magi75-96-aluminum-low-profile-mechanical-keyboard?variant=50355797590322" target="_blank">https://iqunix.com/products/iqunix-magi75-96-aluminum-low-profile-mechanical-keyboard?variant=50355797590322</a></p>

<p>このキーボードも同僚に影響されて買いました。前に買ったキーボードを使い始めて間もなく、オフィスで誰かがこのモデルを購入。実際に何度か試し押ししてみて、私の理想の「矮軸」キーボードだと確信しました。チョコレートスイッチのような感触で、「軽羽軸」は手応えがありつつも静か。見た目も鮮やかで多機能なコントロールパネル付き。何より純正でMacOS用キー配列なのが決め手でした。ようやく手に入れるチャンスができました。</p>

<p><img src="/assets/0d4a5fd2929b/1*qKmRbmaj27xzB1Fdb4elhQ.webp" alt="画像は公式商品画像" loading="lazy" decoding="async" width="1200" height="509" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjUwOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*qKmRbmaj27xzB1Fdb4elhQ.png" /></p>

<p>画像は<a href="https://e.tb.cn/h.iBDV6UGnYYloGER?tk=m11t5opK0Zg" target="_blank">公式商品画像</a>より引用しています。</p>

<h4 id="軸体--カスタムモデル-ライトフェザー軸公式マーケティング文gold-redスイッチ仕様書"><strong>軸体 — カスタムモデル</strong> ライトフェザー軸（公式マーケティング文）、Gold Redスイッチ（仕様書）</h4>

<ul>
  <li>
    <p>押下圧：40 ± 10 Ggf</p>
  </li>
  <li>
    <p>全行程（全距離）：2.8 mm ± 0.25</p>
  </li>
  <li>
    <p>通過ストローク（キーが最上部から押し下げられ、「信号がトリガーされる」瞬間までの距離）：1.2 mm ± 0.30</p>
  </li>
  <li>
    <p>寿命：5,000万回</p>
  </li>
</ul>

<h4 id="キーキャップ">キーキャップ</h4>

<ul>
  <li>
    <p>高含量PBT＋耐汚染コーティング</p>
  </li>
  <li>
    <p>手触りの良い質感</p>
  </li>
</ul>

<h4 id="ケース">ケース</h4>

<ul>
  <li>
    <p>CNC 加工のフルアルミ合金</p>
  </li>
  <li>
    <p>高さ 11 mm（低い部分）— 25.5 mm（高い部分）</p>
  </li>
  <li>
    <p>LE-Tray構造、Poronサンドイッチフォーム、PET底敷、IXPE軸下敷、Poron底フォーム、IXPE底敷</p>
  </li>
</ul>

<h4 id="使用パラメータ">使用パラメータ</h4>

<ul>
  <li>
    <p>Type-C</p>
  </li>
  <li>
    <p>ホットスワップ対応、VIA対応</p>
  </li>
  <li>
    <p>接続方式：有線、Bluetooth 5.1、2.4GHz無線</p>
  </li>
  <li>
    <p>多彩なRGBバックライト制御対応</p>
  </li>
  <li>
    <p>対応OS：Windows / macOS / iOS / Android<br />
交換可能なWindows / macOSキーキャップ付き</p>
  </li>
</ul>

<h4 id="型番-mg65--mg75--mg96--mg65-pro--mg75-pro--mg96-pro">型番 MG65 / MG75 / MG96 / MG65 Pro / MG75 Pro / MG96 Pro</h4>

<p><img src="https://curly-lab-d1bd.zhgchgli-b1d.workers.dev/1*XHoih2u5-Azazt5Gkd1IKA.png" alt="" /></p>

<p>主な違いは、キーボードの配列（65/75/96キー）と、Proには右側にマルチメディアコントロールパネル（+5キー）があることです。</p>

<ul>
  <li>
    <p>MG65: 68キー バッテリー 3,000mAh<br />
900g / MG65 Pro 1030g</p>
  </li>
  <li>
    <p>MG75: 84キー バッテリー 4,000mAh<br />
947g / MG75 Pro 1110g</p>
  </li>
  <li>
    <p>MG96: 100キー バッテリー 4,000mAh<br />
1144g / MG96 Pro 1296g</p>
  </li>
</ul>

<p><strong>マルチメディアコントロールパネル機能：</strong></p>

<p><img src="/assets/0d4a5fd2929b/1*zIGfXexH_24_Pt1sTnVjBA.webp" alt="" loading="lazy" decoding="async" width="1172" height="1042" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTcyIiBoZWlnaHQ9IjEwNDIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/0d4a5fd2929b/1*zIGfXexH_24_Pt1sTnVjBA.png" /></p>

<p>最下部には2.4G USBレシーバー収納スペースがありますが、機能はありません。</p>

<p><strong>外観：</strong></p>

<p><img src="/assets/0d4a5fd2929b/1*D69-323N4fUoRribRtXGnQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="870" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg3MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*D69-323N4fUoRribRtXGnQ.png" /></p>

<ul>
  <li>
    <p>霧蘇ホワイト</p>
  </li>
  <li>
    <p>夜遊ブラック</p>
  </li>
</ul>

<h4 id="価格について">価格について</h4>

<p>タオバオの<a href="https://e.tb.cn/h.iBDV6UGnYYloGER?tk=m11t5opK0Zg" target="_blank"><strong>(天猫 — IQUNIX 公式旗艦店)</strong></a>での2026年5月の販売価格：</p>

<ul>
  <li>
    <p>MG65: 人民元 ¥699</p>
  </li>
  <li>
    <p>MG75: 人民元 ¥899</p>
  </li>
  <li>
    <p>MG96: 人民元 ¥899</p>
  </li>
  <li>
    <p>MG65 Pro: 人民元 ¥899</p>
  </li>
  <li>
    <p>MG75 Pro: 人民元 ¥999</p>
  </li>
  <li>
    <p>MG96 Pro: 人民元 ¥1,099</p>
  </li>
</ul>

<h4 id="選択">選択</h4>

<p>MG65はFキーがないので検討せず、基本はMG75から始めました。MG96は大きすぎる感じがします。Proの機能はあってもなくても良いですが、価格差があまりないためアップグレードしました。<strong>最終的に購入したのはMG75 Proです。</strong></p>

<h4 id="購入経路">購入経路</h4>

<ul>
  <li>
    <p>台湾には代理店がなく、または代理店が既に仕入れを停止しています。</p>
  </li>
  <li>
    <p>海外公式サイト <a href="https://iqunix.com/products/iqunix-magi75-96-aluminum-low-profile-mechanical-keyboard?variant=50355797590322" target="_blank">https://iqunix.com/</a> しかし、価格（MG75Pro）に送料を加えると約 <code class="language-plaintext highlighter-rouge">NT$6,200</code> に近づきます。</p>
  </li>
  <li>
    <p><strong>淘宝公式 <a href="https://e.tb.cn/h.iBDV6UGnYYloGER?tk=m11t5opK0Zg" target="_blank">IQUNIX 旗艦店</a></strong> MG75PRO 配送料と関税込みで合計 <code class="language-plaintext highlighter-rouge">NT$4,798</code> を支払いました</p>
  </li>
</ul>

<blockquote>
  <p><em>白色は黒色より人気があり、毎週月曜日の発売から週末までに完売します。私は<strong>黒色のMG75 PRO</strong>を購入しました。</em></p>
</blockquote>

<h4 id="淘宝公式-iqunix-公式ショップ"><strong>淘宝公式 <a href="https://e.tb.cn/h.iBDV6UGnYYloGER?tk=m11t5opK0Zg" target="_blank">IQUNIX 公式ショップ</a></strong></h4>

<p>今の時代、淘宝での購入は本当に便利です。自分で集荷や配送方法を調べる必要もなく、中国のアカウントやクレジットカードも不要です。街口、Apple Pay、クレジットカードでオンライン決済が可能で、公式の集荷や直送で自宅まで届けてもらえ、コンビニ受け取りもできます。</p>

<ul>
  <li>
    <p>05/03 深夜に注文し、朝に発送されました</p>
  </li>
  <li>
    <p>05/05 船が出港しました</p>
  </li>
  <li>
    <p>05/06 台湾に到着しました</p>
  </li>
  <li>
    <p>05/08 昼に商品を受け取りました</p>
  </li>
</ul>

<p>海外から商品を購入した経験がない場合は、<a href="https://www.rakuten.com.tw/magazine/life/2022/012802/#D" target="_blank">必ずEZWayの本人認証を完了してください。EZWayアプリをダウンロードし、登録と本人認証を行ってください</a> ；<strong>発送後数日で通関記録の通知が届くので、アプリで確認ボタンを押すだけで完了です。</strong></p>

<h3 id="iqunix-mg75-pro-低軸軽羽軸3モードアルミ合金ケースメカニカルキーボード-ナイトブラック開封レビュー">IQUNIX MG75 Pro 低軸軽羽軸3モードアルミ合金ケースメカニカルキーボード ナイトブラック開封レビュー</h3>

<p><img src="/assets/0d4a5fd2929b/1*8yLYKhBLcd0WbWRXtVteCw.webp" alt="" loading="lazy" decoding="async" width="1200" height="844" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*8yLYKhBLcd0WbWRXtVteCw.png" /></p>

<p>梱包は非常にシンプルで、キーボードと同じ大きさの段ボール箱です…正直、衝撃で壊れないか少し心配でしたが、キーボード収納ケースが硬い素材なので安心です。</p>

<p><img src="/assets/0d4a5fd2929b/1*PL9Fbr5_nRpgLEgKtrcVJA.webp" alt="" loading="lazy" decoding="async" width="1200" height="849" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*PL9Fbr5_nRpgLEgKtrcVJA.png" /></p>

<p>開けるとすぐにキーボード収納バッグがあり、梱包はそのまま段ボール箱に入っているだけです。</p>

<p><img src="/assets/0d4a5fd2929b/1*-hTJy3Cz8YSTFHX60HRzlg.webp" alt="" loading="lazy" decoding="async" width="569" height="178" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjkiIGhlaWdodD0iMTc4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/0d4a5fd2929b/1*-hTJy3Cz8YSTFHX60HRzlg.png" /></p>

<p>公式の商品ページの説明によると、新しいパッケージで、キーボード収納バッグに直接変更されている（つまり、もう一つ箱が無料で付いてくる）ようです。</p>

<p><img src="/assets/0d4a5fd2929b/1*o4caqnDEgtJQBynfPEEKAg.webp" alt="" loading="lazy" decoding="async" width="1690" height="1240" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNjkwIiBoZWlnaHQ9IjEyNDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/0d4a5fd2929b/1*o4caqnDEgtJQBynfPEEKAg.png" /></p>

<p>キーボードのパッケージを開けると、本体、説明書、付属品が入っています。</p>

<p><img src="/assets/0d4a5fd2929b/1*aRdH-fuap85bju8r5WHMdg.webp" alt="" loading="lazy" decoding="async" width="1602" height="1205" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNjAyIiBoZWlnaHQ9IjEyMDUiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/0d4a5fd2929b/1*aRdH-fuap85bju8r5WHMdg.png" /></p>

<p>付属品は、2.4GHzレシーバー、USB-A to USB-Cケーブル、予備のキーキャップ、キーキャッププラーです。</p>

<p><img src="/assets/0d4a5fd2929b/1*lqklyMPAqRFuNskhqcJwrg.webp" alt="" loading="lazy" decoding="async" width="1200" height="887" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg4NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*lqklyMPAqRFuNskhqcJwrg.png" /></p>

<p>工場出荷時は macOS 用キーキャップが装着されていますが、付属のXアルミニウムキーキャップに交換して質感を高めるかはお好み次第です。付属のデータケーブルはスプリングケーブルで、伸ばせる長さが長く収納もしやすい点が良いです。</p>

<p><img src="/assets/0d4a5fd2929b/1*DZJLlUoscPXZsDWKq7sVpw.webp" alt="" loading="lazy" decoding="async" width="1594" height="621" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTk0IiBoZWlnaHQ9IjYyMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*DZJLlUoscPXZsDWKq7sVpw.png" /></p>

<p>キーボードの裏面も金属感があり、とても高級感があります。唯一の欠点は、角度調整ができる内蔵スタンドがないことです。</p>

<p><img src="/assets/0d4a5fd2929b/1*IbjacAUuMmG36KG1yAA11w.webp" alt="" loading="lazy" decoding="async" width="1724" height="1038" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNzI0IiBoZWlnaHQ9IjEwMzgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/0d4a5fd2929b/1*IbjacAUuMmG36KG1yAA11w.png" /></p>

<p>キーの高さは元のキーボードと比べてどうか。</p>

<p><img src="/assets/0d4a5fd2929b/1*8Q3XPHzX7coQBMmshcxLlQ.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/0d4a5fd2929b/1*8Q3XPHzX7coQBMmshcxLlQ.jpeg" /></p>

<p>直接Xに交換しました。</p>

<h4 id="本体の詳細">本体の詳細</h4>

<p><img src="/assets/0d4a5fd2929b/1*CsWUoUK0HSqcgPJ7rWFMBw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*CsWUoUK0HSqcgPJ7rWFMBw.jpeg" /></p>

<p>購入時に気づかなかったのですが、このパネルには光るライトバーが付いていました。</p>

<p><img src="/assets/0d4a5fd2929b/1*_-epZwLtuUlUBwUolthLgw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*_-epZwLtuUlUBwUolthLgw.jpeg" /></p>

<p><img src="/assets/0d4a5fd2929b/1*eCMkEokNFYEDkdmPkqGpeg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*eCMkEokNFYEDkdmPkqGpeg.jpeg" /></p>

<p><img src="/assets/0d4a5fd2929b/1*aJ3Q02uvkViRzL2eoQYXYQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*aJ3Q02uvkViRzL2eoQYXYQ.jpeg" /></p>

<p><img src="/assets/0d4a5fd2929b/1*bYC27o6XOVINVrab6Nq7rQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="901" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*bYC27o6XOVINVrab6Nq7rQ.png" /></p>

<p><img src="/assets/0d4a5fd2929b/1*nAz4ZUL677wsJsYBf7Zz-g.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*nAz4ZUL677wsJsYBf7Zz-g.jpeg" /></p>

<p>キー本体は落ち着いた黒のマット仕上げで、キーボード本体はマットなアルミ合金製で非常に高級感があり、手に持つと重厚で実用的です。</p>

<h4 id="説明書">説明書</h4>

<p><img src="/assets/0d4a5fd2929b/1*kuAtQ-dLWNNAjm37DuTWwA.webp" alt="" loading="lazy" decoding="async" width="1200" height="455" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQ1NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/0d4a5fd2929b/1*kuAtQ-dLWNNAjm37DuTWwA.png" /></p>

<p>基本的には他のメカニカルキーボードとほとんど同じで、ライトの調整と接続方法の設定だけです。</p>

<h4 id="起動プロセス">起動プロセス</h4>

<ul>
  <li>
    <p>ケーブルをパソコンに接続する</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">FN + ESC</code> を3秒以上長押ししてキーボードの電源をオンにする（Tabのバックライトが点滅します）</p>
  </li>
  <li>
    <p>macOSキー配列に切り替え：<code class="language-plaintext highlighter-rouge">FN + Tab</code> <strong>（macOSでは必ず設定してください。設定しないとCMDキーがCTRLキーとして動作します）</strong></p>
  </li>
  <li>
    <p>バックライト設定：<code class="language-plaintext highlighter-rouge">FN + [</code> / <code class="language-plaintext highlighter-rouge">FN + ]</code> / <code class="language-plaintext highlighter-rouge">FN + Shift</code> / <code class="language-plaintext highlighter-rouge">FN + Enter</code></p>
  </li>
</ul>

<p><img src="/assets/0d4a5fd2929b/1*2XHm8O4TUpCVmHiF0GrIrQ.webp" alt="" loading="lazy" decoding="async" width="2048" height="1536" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDQ4IiBoZWlnaHQ9IjE1MzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/0d4a5fd2929b/1*2XHm8O4TUpCVmHiF0GrIrQ.jpeg" /></p>

<h4 id="実際のキー音">実際のキー音</h4>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/Md2yzNBa1K4" title="IQUNIX MG 65/75/96 Pro 矮軸輕羽軸三模鋁合金外殼機械鍵盤夜遊黑開箱、按鍵聲音" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<blockquote>
  <p><em>iPhoneの録音特性により実際の音量より大きく聞こえるため、対比の大きさを重視してください。</em></p>
</blockquote>

<h4 id="使用感触">使用感触</h4>

<p>音は元よりも落ち着いて静かになりつつも、メカニカルキーボードのフィードバック感は失われていません。現在使っていてとても快適です。欠点は右側のキーが密集していて慣れていないと間違えて押しやすいことです。例えば、削除キーを押そうとしてホームキーを押してしまうことがあります。</p>

<p><em><a href="https://medium.com/zrealm-life/iqunix-mg-65-75-96-pro-%E7%9F%AE%E8%BB%B8%E8%BC%95%E7%BE%BD%E8%BB%B8%E4%B8%89%E6%A8%A1%E9%8B%81%E5%90%88%E9%87%91%E5%A4%96%E6%AE%BC%E6%A9%9F%E6%A2%B0%E9%8D%B5%E7%9B%A4%E5%A4%9C%E9%81%8A%E9%BB%91%E9%96%8B%E7%AE%B1-0d4a5fd2929b" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>によって変換されました。</em></p>]]></content>
  </entry><entry>
    <title type="html">AI AgentでGoogle Apps Script開発を効率化｜ゼロから始めずに自動化を実現</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ai-agent%E3%81%A7google-apps-script%E9%96%8B%E7%99%BA%E3%82%92%E5%8A%B9%E7%8E%87%E5%8C%96-%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E5%A7%8B%E3%82%81%E3%81%9A%E3%81%AB%E8%87%AA%E5%8B%95%E5%8C%96%E3%82%92%E5%AE%9F%E7%8F%BE-35cc65327d28/" rel="alternate" type="text/html" title="AI AgentでGoogle Apps Script開発を効率化｜ゼロから始めずに自動化を実現" />
    <published>2026-05-03T21:06:17+08:00</published>
    <updated>2026-05-03T21:28:55+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/35cc65327d28</id><summary type="html">プログラミング初心者も安心。AI AgentがGoogle Apps Scriptの連携・開発をサポートし、手間を大幅削減。Claude Design &amp; Claude Codeで自分だけのダッシュボードを簡単作成し、作業効率アップを実感しよう。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="クロードコード" /><category term="グーグルアプリスクリプト" /><category term="ダッシュボード" /><category term="ai" /><category term="クロード" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/35cc65327d28/1*QFRr50u8zbS5WtVtvprG9w.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ai-agent%E3%81%A7google-apps-script%E9%96%8B%E7%99%BA%E3%82%92%E5%8A%B9%E7%8E%87%E5%8C%96-%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E5%A7%8B%E3%82%81%E3%81%9A%E3%81%AB%E8%87%AA%E5%8B%95%E5%8C%96%E3%82%92%E5%AE%9F%E7%8F%BE-35cc65327d28/"><![CDATA[<h3 id="ゼロから始めるのはもうやめよう-aiが直接google-apps-scriptの連携と開発を代行します">ゼロから始めるのはもうやめよう AIが直接Google Apps Scriptの連携と開発を代行します</h3>

<p>AIで無駄を宝に変える — Claude Design &amp; Claude Codeを使ってあなた専用のパーソナルデスクトップダッシュボードを作る例。</p>

<p><img src="/assets/35cc65327d28/1*QFRr50u8zbS5WtVtvprG9w.webp" alt="" loading="lazy" decoding="async" width="1448" height="1086" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDQ4IiBoZWlnaHQ9IjEwODYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/35cc65327d28/1*QFRr50u8zbS5WtVtvprG9w.png" /></p>

<h4 id="完成品デモ">完成品デモ</h4>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/Zu0rbnu_iy8" title="AI 變廢為寶 - 用 Claude Design &amp; Claude Code 打造屬於你的個人桌面 Dashboard" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<blockquote>
  <p><em>長年引き出しに眠っていたiPhone 8 Plusが、完全にカスタマイズ可能で無料の個人用デスクトップダッシュボードに生まれ変わりました。</em></p>
</blockquote>

<h3 id="はじめに">はじめに</h3>

<blockquote>
  <p><strong><em>TL;DR あなたがAIを使って自分だけのパーソナルデスクトップダッシュボードを作る方法にだけ興味があるなら、この章は飛ばしてください。</em></strong></p>
</blockquote>

<p>大体的に2021年頃からGoogle Apps Scriptを使って、小さなツールを開発し、自動化でワークフローを最適化してきました。その当時はAIもなく、RPAによる自動化もほとんど話題になっていませんでした。ただ単純にチームの協力効率を上げたり、個人の生活の快適さを向上させたりしたかっただけで、すべてのスクリプトは自分で一行一行手書きしていました（今から見ると昔ながらのプログラミングです）。<strong>しかし、一番難しいのはプログラミングそのものではなく、どうやって連携するか？どうやって連携すればいいのか？思考をどう枠から抜け出すか？ということでした。</strong></p>

<h4 id="以前に行った事例">以前に行った事例</h4>

<ol>
  <li>
    <p><strong>目標 — 外部公開のメール窓口で受信したメールを Slack の作業チャンネルに転送したい。</strong><br />
<strong>技術的に Google Apps Script は Gmail 受信時のイベントを持っていない</strong>ため、別の方法としてスケジュール機能を使い、毎分（またはそれ以上の間隔）に実行：未読メールをチェック ➡️ 内容を読み取り ➡️ HTMLを除去して Slack に転送 ➡️ 既読にする。<br />
特定のメール（送信者や件名内容）だけを対象にしたい場合は、Gmailでラベルフィルターを設定し、未読メールのチェックを未読＋ラベルに変更すれば実現可能。<br />
ref: 「 <a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-scriptでgmailをslackに自動転送-フィルター連携で効率化-d414bdbdb8c9/">運用 Google Apps Script で Gmail メールを Slack に転送</a> 」</p>
  </li>
  <li>
    <p><strong>目標 — GAのトラフィックやCrash-free rateを自動でSlackの作業チャンネルに送信する。</strong><br />
Google Apps ScriptにはAnalyticsDataやAdSenseのライブラリが標準で用意されており、パラメータを設定するだけでほぼ無痛で統合できます。<br />
アプリでクラッシュの詳細やTop 10のIssueを調べたい場合は、さらに<strong>FirebaseからBigQueryへ</strong>データを連携し、Google Apps ScriptでBigQueryライブラリを読み込み、SQLクエリを実行すれば可能です。<br />
ref: 「 <a href="/posts/zrealm-ロボティック-プロセス-オートメーション/crashlyticsとgoogle-analytics連携-appのcrash-free-users率を自動取得する方法-793cb8f89b72/">Crashlytics + Google Analytics 自動查詢 App Crash-Free Users Rate</a> 」、「 <a href="/posts/zrealm-ロボティック-プロセス-オートメーション/crashlyticsとbig-query連携-slackで即時にクラッシュ追跡を実現-e77b80cc6f89/">Crashlytics + Big Query 打造更即時便利的 Crash 追蹤工具</a> 」</p>
  </li>
  <li>
    <p><strong>目標 — 自動で運営データを Google Sheet に集約する。</strong><br />
前述の方法に加え、チームのテレビウォールで運営データを一目で確認できるように Web App を作成しました。<strong>当時の技術的な問題は、一部のデータが社内ネットワークにあり</strong>、外部ネットからアクセスできなかったことです。幸いにも、逆に社内ネットワーク側でスケジュールを組み、毎日データを Google Apps Script の Web App に送信し、受信後に処理して Google Sheet に反映させました。<br />
ref:「 <a href="/posts/zrealm-ロボティックプロセスオートメーション/google-apps-scriptで毎日データ報告をrpa自動化-効率化と正確性向上の秘訣-f6713ba3fee3/">使用 Google Apps Script 實現每日數據報表 RPA 自動化</a> 」</p>
  </li>
  <li>
    <p><strong>目標 — 既存のリソースで簡単なアプリパッケージングプラットフォームを構築する</strong><br />
当時の背景は、アプリのパッケージングサービスがGitHub Actionsに移行したことですが、非エンジニアチームもアプリのパッケージングが必要で、以前は手作業で対応していました。そこで、社内チーム全員が使えるサービスとしてGitHub Actionsを連携してパッケージングを実行する仕組みが求められました。<br />
Google Apps ScriptのWebアプリをプラットフォームとして使用し、組織内のアカウントのみ利用可能に制限。フォームにパッケージング情報を入力するとGitHub Actions（GitHub API）をトリガーし、パッケージング完了のSlack通知を送信します。<br />
パッケージングしたアプリはFirebase App Distributionにアップロードしますが、<strong>Google Apps Scriptには組み込みのライブラリはありません。しかし<a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-script-firebase-app-distribution-apiとの高速連携方法-効率的なgoogle-apis統合-71400d408dc8/">調べたところ googleapis を直接使えることがわかり</a>、最終的には問題なく連携できました。</strong><br />
ref:「 <a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/">Google Apps Script Web AppでGitHub Actionsを連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</a> 」</p>
  </li>
</ol>

<p>まだ小さな事例は挙げませんが、<strong>とにかく伝えたいのは「方法は困難より多い」ということです。実際にプログラムを書くこと自体は一番簡単で、いかに多くの障害を乗り越えて連携させるかが難しいのです</strong>。</p>

<h4 id="技術的な制限">技術的な制限</h4>

<p>「方法は困難より多い」という前提は、<strong>技術的に可能で合理的であること</strong>です。言い換えれば、「方向が間違っていれば、努力しても無駄」です。実際にプログラムを書かなくても、Google Apps Scriptを使ってツールを開発するタイミングを「選択」できることを必ず知っておくべきです。</p>

<ul>
  <li>
    <p><strong>User-Agent をカスタマイズできない：</strong> セキュリティと悪用防止のため、Google Apps Script の User-Agent は指定できません。（ただし他の Header フィールドは指定可能です）<br />
<strong>影響：</strong> 一部の特殊な API サービスでは User-Agent にデータを含める必要があったり、対象のサイトや API が Google Apps Script の User-Agent をブロックしている場合があります。これらは厳しい制限であり、使用できません。<br />
<strong>回避策：</strong> <a href="https://zhgchg.li/posts/88f0fb935120/" target="_blank">どうしても使いたい場合は Cloudflare Worker を使って Proxy 経由で接続する方法があります。</a></p>
  </li>
  <li>
    <p><strong>最長実行時間 6分：</strong> 1回の実行は最大6分までで、処理が大きすぎる場合は分割することを推奨します。<br />
また、トリガーの合計実行時間にも上限があり、1日あたり最大90分まで実行可能です。<strong>（ただし、これはソフトリミットのようで、私のスクリプトは多くが上限を超えていますが、ブロックされていません）</strong></p>
  </li>
  <li>
    <p><strong>単一実行は同期ブロッキングが基本</strong> ：単一の実行内で複数のスレッドを並行処理することはできません。処理に時間がかかる場合や大量の並行処理が必要な場合は、複数回に分けて実行し、スケジュールでトリガーすることを推奨します。</p>
  </li>
  <li>
    <p><strong>コールドスタート：</strong> Faasサービスの共通の問題で、タスクが長時間トリガーされないとスリープ状態になり、再度トリガーされる際に待機時間が長くなることがあります。<br />
この問題に加え、タスクが同期（ブロッキング）実行である制限があるため、Webhookとして他のサービスから呼び出すとリクエスト失敗と判断されやすく、リクエストの重複送信や重複受信、重複実行が起こる可能性があります。<br />
例えば、SlackはWebhookサーバーが3秒以内に応答することを厳しく要求しており、過去の経験ではこの問題に頻繁に直面しました。</p>
  </li>
  <li>
    <p><strong>Web App API はリダイレクトします：</strong> セキュリティ上の理由から、Content service が返す内容は一度使い切りの <code class="language-plaintext highlighter-rouge">script.googleusercontent.com</code> URL にリダイレクトされます。HTTP クライアントはリダイレクトのフォローに対応している必要があります。<br />
一部のWebhookサービスは自動で302リダイレクトしないと失敗します（例：Jira Webhook）。</p>
  </li>
  <li>
    <p><strong>Web App HTML</strong> ：ウェブページの上部に不正利用防止の声明があり、本当のRWD（レスポンシブデザイン）は実現できません（ページは実際にはGoogleのフレーム内のiframeです）。URLが見栄えが悪くカスタマイズできず、PWAの全画面表示もできません。</p>
  </li>
</ul>

<p><img src="/assets/35cc65327d28/1*NI80VyLt-hHAKJskJLdTmg.webp" alt="" loading="lazy" decoding="async" width="693" height="196" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2OTMiIGhlaWdodD0iMTk2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/35cc65327d28/1*NI80VyLt-hHAKJskJLdTmg.png" /></p>

<ul>
  <li><strong>サービス制限：</strong> 一部のサービスには利用制限がありますが、通常の使用では上限に達することはほとんどありません。ただし、高頻度でリアルタイムのチェックや応答が必要な場合は、制限に引っかかりやすくなります。</li>
</ul>

<p><img src="/assets/35cc65327d28/1*bg8nLfiGaVJ7xqhIQewp1g.webp" alt="&lt;https://developers.google.com/apps-script/guides/services/quotas?hl=zh-tw&gt;" loading="lazy" decoding="async" width="1200" height="954" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk1NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*bg8nLfiGaVJ7xqhIQewp1g.png" /></p>

<p><a href="https://developers.google.com/apps-script/guides/services/quotas?hl=zh-tw" target="_blank">https://developers.google.com/apps-script/guides/services/quotas?hl=zh-tw</a></p>

<h4 id="優位性と機能">優位性と機能</h4>

<p>制限を理解した上で、どのような利点や機能があるか見てみましょう。</p>

<p>最大の利点は、Google純正の関連サービスと直接シームレスに連携できることです。Webアプリのアクセス権は、スクリプト所有者本人、組織内のメンバー、Googleにログインしているアカウント、全員から選択可能で、<strong>複雑なOAuthの手続きを自分で行う必要がなく、ワンクリックで設定・完了・実行が可能</strong>です：</p>

<p><strong>組み込みサービス Built-in Services:</strong>
<strong>GASサービスで参照しなくても使用可能。</strong></p>

<ul>
  <li>
    <p>DocumentApp → Google ドキュメント</p>
  </li>
  <li>
    <p>SpreadsheetApp → Google スプレッドシート</p>
  </li>
  <li>
    <p>SlidesApp → Google スライド</p>
  </li>
  <li>
    <p>FormApp → Google フォーム</p>
  </li>
  <li>
    <p>GmailApp → Gmail</p>
  </li>
  <li>
    <p>CalendarApp → Google カレンダー</p>
  </li>
  <li>
    <p>DriveApp → Google ドライブ</p>
  </li>
  <li>
    <p>SitesApp → Google サイト</p>
  </li>
  <li>
    <p>Maps → マップ / 距離 / ルート</p>
  </li>
  <li>
    <p>翻訳</p>
  </li>
</ul>

<p><strong>高度なサービス Advanced Services:</strong>
<strong>GASサービスで参照を追加する必要があります。</strong></p>

<ul>
  <li>
    <p>Sheets API</p>
  </li>
  <li>
    <p>Drive API</p>
  </li>
  <li>
    <p>Calendar API</p>
  </li>
  <li>
    <p>Gmail API</p>
  </li>
  <li>
    <p>Analytics API / Analytics Data API</p>
  </li>
  <li>
    <p>BigQuery API</p>
  </li>
  <li>
    <p>Adsense API</p>
  </li>
  <li>
    <p>YouTube Data API</p>
  </li>
  <li>
    <p>Tasks API</p>
  </li>
  <li>
    <p>Googleapis（その他/GCP）</p>
  </li>
</ul>

<p><strong>ツール / システムサービス:</strong></p>

<ul>
  <li>
    <p>UrlFetchApp → 外部APIを呼び出す</p>
  </li>
  <li>
    <p>PropertiesService → キー・バリューの保存</p>
  </li>
  <li>
    <p>CacheService → キャッシュ</p>
  </li>
  <li>
    <p>LockService → 同時実行制御</p>
  </li>
  <li>
    <p>Utilities → 日付 / ハッシュ / Base64</p>
  </li>
  <li>
    <p>Logger → ログ出力</p>
  </li>
  <li>
    <p>HtmlService → Web UIを作成し、Ajax非同期でコンテンツを更新することをサポートする</p>
  </li>
  <li>
    <p>ContentService → APIエンドポイントの作成</p>
  </li>
  <li>
    <p>Trigger → トリガーによる自動実行</p>
  </li>
</ul>

<p>基本的に開発に必要なものはすべて揃っています。実務ではこれらのサービスを組み合わせて連携させることで、ワークフローの自動化が実現できます。例えば：</p>

<ul>
  <li>
    <p>自動で GA トラフィック／Crash-free rate を Slack 作業チャンネルに送信：<br />
Analytics Data API でデータ取得、PropertiesService で Slack Bot トークンを保存、UrlFetchApp で Slack Send Message API を呼び出し</p>
  </li>
  <li>
    <p>自動で運営データを Google Sheet とデータ Dashboard Web に集約：<br />
Trigger でスケジュール実行する関数、LockService で自分だけが実行していることを保証、Analytics Data API でデータ取得、UrlFetchApp で外部サービスのデータ取得、SpreadsheetApp で Google Sheet に書き込み、HtmlService で Web アプリのインターフェースを出力、ContentService で JSON データを出力＋CacheService でデータキャッシュ</p>
  </li>
</ul>

<h4 id="cloud-function--lambda-のようなfaasとの違い">Cloud Function / Lambda のようなFAASとの違い</h4>

<p>Google Apps Script は Google サービスを中心とした FAAS スクリプトツールと見なせます。制限は多いですが、<strong>現在は完全無料で、Google サービスとスムーズに連携できます；</strong> 他の FAAS サービスは通常有料で、一部無料枠がありますが、Google サービスとの連携には正式な IAM や OAuth フローが必要で、やや複雑です。</p>

<h4 id="不適切なシーン">不適切なシーン</h4>

<ul>
  <li>
    <p>Googleファミリー以外、例えばMicrosoft OfficeやOneNoteと連携したい場合…</p>
  </li>
  <li>
    <p>オンプレミスとクラウドのハイブリッド環境には、n8nやAIエージェントがより適しています。</p>
  </li>
  <li>
    <p>複雑な計算や大量のデータ処理では、各実行セッションが最大6分で終了しないことがあります。</p>
  </li>
  <li>
    <p>大規模なウェブサイトのクロールやチケット争奪プログラムは避けた方がいいです。Google Apps Scriptは簡単にブロックされたり、Cloudflareのアンチスクレイピングに阻まれたりします。</p>
  </li>
</ul>

<h4 id="適したシーン">適したシーン</h4>

<p>個人やチーム内のワークフロー連携について、私の場合は日常のルーチン作業を管理するために多くのスクリプトを使っています。例えば、毎日 <a href="https://zhgchg.li/" target="_blank">zhgchg.li</a> のサイトトラフィック概要を通知したり、GitHubリポジトリのIssuesを管理したり、保有株のGoogle Sheets上の現在価格を更新したりしています。チームの場合は、アプリのリリースプロセスをGoogleカレンダーと連携させ、カレンダーイベントをチェックして対応するCI/CDプロセス（GitHub Actionsの呼び出し）をトリガーし、チームのSlackチャンネルにメッセージを送信したり、アプリ審査失敗のメールをSlackに転送したりしています。</p>

<blockquote>
  <p><em>以上は人間の視点でここ数年のGoogle Apps Script開発の感想を振り返ったもので、<strong>次に最近使い始めたAIエージェントに0から直接GASを開発してもらった実感と実例—個人用デスクトップDashboard Deck</strong>についてです。</em></p>
</blockquote>

<h4 id="aiエージェントにgoogle-apps-scriptの連携と開発を直接任せる">AIエージェントにGoogle Apps Scriptの連携と開発を直接任せる</h4>

<p>最近、0からAIを使って直接Google Apps Scriptを開発することを試み始めました。上記の基礎知識と組み合わせて（<strong>知識がなくてもAIの理解度は非常に高いです</strong>）、<strong>完成度と正確性はほぼ100%</strong>です。「ゼロからAIがプログラムを書く」時代は終わったと言えるでしょう。</p>

<h3 id="実践--aiで廃棄物を宝に--claude-design--claude-codeを使ってあなた専用の個人デスクトップダッシュボードを作成する">実践 — AIで廃棄物を宝に — Claude Design &amp; Claude Codeを使ってあなた専用の個人デスクトップダッシュボードを作成する</h3>

<h4 id="問題">問題</h4>

<p>ずっと引き出しにしまって使っていなかったiPhone 8 Plus（iOS 16.7）を、デスクトップの小さな画面として使い、見たいリアルタイム情報を表示できるダッシュボードにしようと思いました。</p>

<h4 id="基礎インフラ">基礎インフラ</h4>

<p>AIエージェントにGoogle Apps Scriptの開発を手伝ってもらうためには、いくつかの基本的なインフラを整える必要があります。</p>

<blockquote>
  <p><em>AI開発でなくても、中〜大規模のスクリプト開発時には必ず使用することを強くおすすめします。Webエディタは時々クラッシュしたり、誤って複数のタブを開いて古いコードが新しいコードを上書きすることがあります。Claspを使うと、より便利で安全にソースコードの管理・作成ができます。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>その他の使用例：</em></strong> <em>Google Apps Script プロジェクトを同時に Git リポジトリにアップロードしてバージョン管理（<code class="language-plaintext highlighter-rouge">.clasprc.json</code> と <code class="language-plaintext highlighter-rouge">.clasp.json</code> を除外）、CI で Jest JS の単体テストを自動実行、CD で Clasp トークンを使って最新コードを取得、.claspignore で Google Apps Script プロジェクトにアップロードしないファイルを除外可能。</em></p>
</blockquote>

<ol>
  <li>インストール <a href="https://codelabs.developers.google.com/codelabs/clasp?hl=zh-tw#1" target="_blank"><strong>clasp Google Apps Script CLI</strong> ( 公式 ローカル開発キット)</a></li>
</ol>

<ul>
  <li>
    <p>Node.js &gt;= 20.0.0 ( <a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm" target="_blank">Node.js環境がインストールされていない場合は、先にインストールしてください</a> )</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">npm i @google/clasp -g</code></p>
  </li>
</ul>

<ol>
  <li>
    <p><code class="language-plaintext highlighter-rouge">clasp login</code> を実行してログインし、認証トークンを生成する（<a href="https://script.google.com/home" target="_blank">Google Apps Script に対応するアカウントを選択</a>）</p>
  </li>
  <li>
    <p>clasprc（Claspトークン）をKeychainに保存してAIエージェントが安全に呼び出せるようにする</p>
  </li>
</ol>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>security add-generic-password <span class="se">\</span>
  <span class="nt">-U</span> <span class="se">\</span>
  <span class="nt">-s</span> <span class="s2">"com.google.clasp"</span> <span class="se">\</span>
  <span class="nt">-a</span> <span class="s2">"</span><span class="nv">$USER</span><span class="s2">"</span> <span class="se">\</span>
  <span class="nt">-w</span> <span class="s2">"</span><span class="si">$(</span><span class="nb">cat</span> ~/.clasprc.json<span class="si">)</span><span class="s2">"</span>
</code></pre></div></div>

<h1 id="これはパスワードをキーチェーンに追加するコマンドです">これはパスワードをキーチェーンに追加するコマンドです</h1>

<p>もし Clasp トークンをコピーして CI/CD の Secret に設定してタスクを実行したい場合は、<code class="language-plaintext highlighter-rouge">cat ~/.clasprc.json \\| base64 \\| pbcopy</code>（base64 エンコードを忘れずに）を使います。使用時は <code class="language-plaintext highlighter-rouge">echo "$CLASPRC" \\| base64 --decode &gt; ~/.clasprc.json &amp;&amp; chmod 600 ~/.clasprc.json</code> とします。</p>

<ol>
  <li>プロジェクトディレクトリの作成</li>
</ol>

<p><img src="/assets/35cc65327d28/1*W5Y_173DcbwNeNZ8aeSGsA.webp" alt="" loading="lazy" decoding="async" width="219" height="36" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMTkiIGhlaWdodD0iMzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/35cc65327d28/1*W5Y_173DcbwNeNZ8aeSGsA.png" /></p>

<p>プロジェクトディレクトリを作成してから移動する必要があります。</p>

<ol>
  <li>ディレクトリ内に Google Apps Script プロジェクトを作成する（clasp を使用）</li>
</ol>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>clasp create
</code></pre></div></div>

<blockquote>
  <p><em>ディレクトリ名をそのままプロジェクト名として使用します。</em></p>
</blockquote>

<p><img src="/assets/35cc65327d28/1*4OjgluUubwvz0cOrs3DZ9g.webp" alt="" loading="lazy" decoding="async" width="888" height="69" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4ODgiIGhlaWdodD0iNjkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/35cc65327d28/1*4OjgluUubwvz0cOrs3DZ9g.png" /></p>

<p>現在のプロジェクトは空で、<code class="language-plaintext highlighter-rouge">appsscript.json</code> という設定ファイルだけがあります。</p>

<h4 id="私のデザイン">私のデザイン</h4>

<p><a href="https://github.com/zhgchgli0718/GASDashboardExample" target="_blank"><img src="https://opengraph.githubassets.com/7f1fca54b1504ffaae1102433fb1baff9a4165f507554bb5b745851eefd4eb27/zhgchgli0718/GASDashboardExample" alt="" /></a></p>

<blockquote>
  <p><em>もしTokenを節約したい場合は、私のGAS Web Appを直接git cloneして、私のデザインや開発済みのGASコードを再利用できます。</em></p>
</blockquote>

<h4 id="claude-design-または-design-agent-skill-を使ってダッシュボードを設計する">Claude Design または Design Agent Skill を使ってダッシュボードを設計する</h4>

<p><strong>方式 1 — Claude Design</strong><br />
前回の記事「 <a href="https://zhgchg.li/posts/zrealm-dev/jekyll-blog-%E8%87%AA%E8%A8%82%E4%B8%BB%E9%A1%8C%E8%A8%AD%E8%A8%88-%E7%94%A8-claude-design-claude-code-%E5%BF%AB%E9%80%9F%E6%89%93%E9%80%A0%E5%B0%88%E5%B1%AC%E9%A2%A8%E6%A0%BC-6bf79c5b4dab/#%E5%AF%A6%E7%8F%BE%E6%AD%A5%E9%A9%9F" target="_blank">Jekyll Blog カスタムテーマ設計｜Claude Design + Claude Code で専用スタイルを素早く作成</a> 」で紹介したように、同じ手順で満足いくデザインに調整し、Project をエクスポートして解凍後、プロジェクトの <code class="language-plaintext highlighter-rouge">./Design</code> フォルダに配置します。</p>

<p><strong>方式 2 — Design Agent Skill</strong><br />
サードパーティの<a href="https://github.com/alchaincyf/huashu-skills" target="_blank">設計 Skill</a>を使ってデザインを完成させます。私のプロンプトはおおよそ以下の通りです:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/huashu-design
iPhone 8 Plus の横向き表示に対応したウェブダッシュボードを設計し、デザイン結果を ./Design フォルダに保存する
- 後で Google Apps Script Web App にデプロイ予定
- 上部には日付と曜日、ページ切替時の時計を固定表示
- 下部のタブは定期的に切り替わり、進行状況バーを表示
- 下部タブの内容：
-- 天気情報
-- カレンダー：現在の予定または当日の直近の予定、残りのイベントを表示
-- カウントダウン/カウントアップ日数
</code></pre></div></div>

<blockquote>
  <p><em>私は Model: Opus 4.7 (1M コンテキスト) / 努力度: 中程度 を使用しています</em></p>
</blockquote>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
⏺ まず状況を把握しました：iPhone 8 Plus 横向き = 736×414 CSS px、内容データ構造（天気 / カレンダー / カウントダウン）は CLAUDE.md に明確に定義済みです。
  スタイルはまだ指定されていませんので、「デザイン方向アドバイザー」として3つの明確に異なる流派の方向性を提示します。どれか一つ（または混ぜても可、例："Aのフォント + Cの配色"）を選んでください。そこから完全なハイファイを作成します。
<span class="p">  ---</span>
  🅐 方向一 · Massimo Vignelli 式スイスグリッド（情報建築派）
  ▎ Vignelliがニューヨーク地下鉄のために設計したグリッド美学——Helvetica + 厳格なカラム + 赤黒白の三色。情報自体が装飾であり、イラストやアイコン、グラデーションに頼らない。
<span class="p">  -</span> フォント：Neue Haas Grotesk / Inter Tight（ディスプレイ）+ IBM Plex Mono（時計/数字）
<span class="p">  -</span> 配色：純白背景 #FAFAFA · 純黒インク #0A0A0A · 単一朱赤アクセント #E63946（進捗バーと現在タブに使用）
<span class="p">  -</span> レイアウト：12カラムベースライングリッドで全要素を揃える；ページめくり時計は黒背景白文字の大文字 + 細い水平分割線；タブは角なしのカラーブロック
<span class="p">  -</span> 雰囲気キーワード：理性的 / 控えめ / 印刷物 / 情報密度 / 永遠
<span class="p">  -</span> 適用例：時代を超えた高品質新聞の一面のようなダッシュボードが欲しい場合
<span class="p">  ---</span>
  🅑 方向二 · Dieter Rams × Braun 工業計器（ミニマル産業派）
  ▎ RamsがBraunのためにデザインしたET66電卓、オーディオシステムの美学——淡い米灰色背景 + 角丸ハードウェアパネル + 単一オレンジアクセント +
  ▎ 物理ボタンの質感。各ブロックは独立した計器パネルのよう。
<span class="p">  -</span> フォント：Söhne / Inter（ラベル）+ JetBrains Mono（時計はLCD7セグ風）
<span class="p">  -</span> 配色：暖かい米灰色 #E5E1DA · 深炭色 #2B2B2B · Braunオレンジ #E85D2Cアクセント · ページめくり時計はLCD黄緑 #A8B547のヴィンテージ液晶風
<span class="p">  -</span> レイアウト：各カードに微かな内陰影と1pxのヘアライン枠線を持ち、実物計器の凹み感；タブ切替はボタンの沈み込みのよう
<span class="p">  -</span> 雰囲気キーワード：工業デザイン / 触感 / 1970年代Braun / 落ち着き / エンジニア美学
<span class="p">  -</span> 適用例：ハードウェア感が好きで長時間見ても疲れないものが欲しい場合
<span class="p">  ---</span>
  🅒 方向三 · Teenage Engineering OP-1 / ターミナル（スポーツ詩学派）
  ▎ TEのOP-1シンセサイザーパネルと古いOLED端末美学——深い炭灰色背景 + OLED青緑のグロー + モノスペースフォント + 細かいグリッド背景。ページめくり時計は大型OLED風
  ▎ ページめくり、進捗バーはシーケンサーのステップライトのよう。
<span class="p">  -</span> フォント：JetBrains Mono / IBM Plex Mono（全体）+ Berkeley Mono（大文字ディスプレイ）
<span class="p">  -</span> 配色：背景 #0E0F0D · 主要テキスト #E8E5DA 米白 · OLED青 #9DEF8Fアクセント · 警告オレンジ #FFB454
<span class="p">  -</span> レイアウト：背景に極薄の8pxドットグリッド；ページめくり時計大文字は幅の1/3を占め、わずかな走査線入り；タブ進捗バーはLEDステップ風；天気はASCII風小アイコン
<span class="p">  -</span> 雰囲気キーワード：OLED / サイバーデッキ / アナログシンセ / ハッカーシック / ハッカー文化
<span class="p">  -</span> 適用例：机上で「ウェブページ」ではなく「機器」として見せたい場合
<span class="p">  ---</span>
  どれを選ぶか（またはどの要素を混ぜるか）教えてください。続けて完全なハイファイを ./Design/ に作成します。 また「どれも違うから他の案を」と言ってもらえれば別の流派を提案します。
</code></pre></div></div>

<p>好きなスタイルを選ぶか、AIに自分の希望するスタイルを伝えることもできます。例えば「紙の質感風、アイボリーの和紙＋朱印の美学」など。</p>

<p>AIの設計完了を待っています… <strong>AIは完了後にPlaywrightでスクリーンショットを撮って検証することがあります。トークンを節約したい場合や自分で結果を確認したい場合は、プロンプトにその旨を伝えてください。</strong></p>

<p><strong>目次で直接 .html ファイルをクリックしてデザイン結果を確認：</strong></p>

<p><img src="/assets/35cc65327d28/1*dTXDvk5dttT_RrCTNaSR5w.webp" alt="" loading="lazy" decoding="async" width="1200" height="681" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY4MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*dTXDvk5dttT_RrCTNaSR5w.png" /></p>

<blockquote>
  <p><em>満足するまで調整してから次の開発に進む。</em></p>
</blockquote>

<p><strong><a href="https://docs.google.com/spreadsheets/d/1R98OcfLMB3Dx9MSUsH849ZxLv0Hveh8Py_YxtJ1JljE/edit?usp=sharing" target="_blank">カウントダウン日データソース Google Sheet</a> を作成：</strong></p>

<p><img src="/assets/35cc65327d28/1*Rb4yLjOhg9XwgICKCM7aww.webp" alt="" loading="lazy" decoding="async" width="1056" height="465" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDU2IiBoZWlnaHQ9IjQ2NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*Rb4yLjOhg9XwgICKCM7aww.png" /></p>

<p>最後に、カウントダウンの日付データ用の Google Sheet を作成しておきます。今後データを追加する際は、このシートに追加するだけで済みます。</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>title,date,repeat
誕生日,1994-07-18,yes
日本旅行,2026-12-12,
</code></pre></div></div>

<blockquote>
  <p><em>repeat=yes: 毎年繰り返されるイベント</em></p>
</blockquote>

<blockquote>
  <p><strong><em>Sheet Idをメモする：上の画像のURLの赤い部分 / Gid: 0（最初のシート）</em></strong></p>
</blockquote>

<p><strong>交通部中央気象局 API キーの登録：</strong></p>

<ul>
  <li>
    <p>登録ログイン: <a href="https://opendata.cwa.gov.tw/userLogin" target="_blank">https://opendata.cwa.gov.tw/userLogin</a></p>
  </li>
  <li>
    <p>認証コードの取得</p>
  </li>
</ul>

<h4 id="claude-codeを使ったダッシュボード開発実現">Claude Codeを使ったダッシュボード開発実現</h4>

<p>まずは Claude Code メモリの初期化 Markdown:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/init
⏺ CLAUDE.md を作成し、本リポジトリの現状に焦点を当てています：
  - プロジェクト段階：初期の GAS プロジェクトで、現在は appsscript.json / .clasp.json / Design/Paper Dashboard.html のみで、.gs のコードはまだありません。
  - ファイル用途：manifest 設定（V8、America/New_York、Stackdriver）、clasp による scriptId の紐付け、React+CDN を使った純粋な視覚プロトタイプ（google.script.run は含まれません）。
  - よく使うコマンド：主に clasp（push / pull / open / logs / deploy）、現在は lint や test runner はありません。
  - push 前の注意点：skipSubdirectories: false にすると Design/Paper Dashboard.html も一緒にアップロードされます；manifest に oauthScopes はまだ宣言されていません；タイムゾーン設定の位置。
  - 作業範囲：本リポジトリの内容のみ使用し、他のプロジェクトは参照しないことを明確に要求（あなたの memory ルールに対応）
</code></pre></div></div>

<p>実行プランの開発作業計画:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plan
./Design のダッシュボードウェブ機能とデザインを実現し、Google Apps Script Web App にデプロイする。
- 天気は交通部中央気象署のAPI https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-C0032-00 を使用
- 台北市の天気を表示し、ある項目はすべて表示する
- 開発段階では自分でトークンを生成し、Web App をデプロイして必要なメソッドを自主的にトリガーしテスト検証できる。開発完了後は必ずこの入口を削除すること
- Web App は全員アクセス可能にデプロイするが、カスタムトークンで保護し、初回使用時はユーザーがトークンを入力するかURLから渡す
- カレンダーはデフォルトで primary を読み取る
- カウントダウン日は提供された Google Sheet から title, date, repeat を読み取る。repeat が yes の場合は年単位の繰り返しカウントダウンで、経過した年と月も表示（切り捨て）
- APIキー、Google Sheet ID/GID などはすべて PropertiesService に設定する
- clasp push &amp; deploy を直接使用し、clasprc のログイントークンは keychain security add-generic-password \ -U \ -s "com.google.clasp" \ -a "$USER" で登録する
- 手動で対応が必要な箇所はすべて繁体字中国語で手順を教えてほしい
- oauthScopes": [ "https://www.googleapis.com/auth/script.external_request", "https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/script.scriptapp" ]
- google.script.run の連携利用フォーマットが正しいか特に確認する
- ライブの GAS Web App HTML は iframe ラッパー内でレンダリングされる
- ./Design など Google Apps Script にアップロード不要のファイルは .claspignore に追加する
</code></pre></div></div>

<ul>
  <li>
    <p>Web App には4つのアクセス権限があります：全員、本人のみ、ログインユーザーのみ、ログイン＆組織内のアカウントのみ</p>
  </li>
  <li>
    <p>上記の例の設計はシンプルで、誰でもアクセス可能ですが、正しいランダムなトークンを入力しないとデータを閲覧できません。天気は自分の地域に変更でき、複数の地域も設定可能です。</p>
  </li>
  <li>
    <p>カレンダーはデフォルトでメインカレンダーのみを処理します。他のカレンダーがある場合は、カレンダーの設定と共有 -&gt; カレンダーの統合 -&gt; カレンダーIDから取得できます。</p>
  </li>
  <li>
    <p><strong>ここに手間を省く開発方法を追加し、AIにテスト用Webアプリの入口を直接デプロイさせて、開発しながらテストと修正を行い、完成したら私に知らせてもらう</strong></p>
  </li>
</ul>

<blockquote>
  <p><em>Planが完了して問題がなければAIに質問し、問題なければ実装を開始できます！</em></p>
</blockquote>

<h4 id="コーヒーを淹れながらai開発を待つ">コーヒーを淹れながらAI開発を待つ…</h4>

<p><img src="/assets/35cc65327d28/1*TEYsNQzxxveclbMvaeAwAw.webp" alt="" loading="lazy" decoding="async" width="1246" height="1318" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjQ2IiBoZWlnaHQ9IjEzMTgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/35cc65327d28/1*TEYsNQzxxveclbMvaeAwAw.png" /></p>

<p><strong>AIエージェントの質問：</strong></p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="n">あなたに必要な操作</span><span class="err">（</span><span class="n">一度だけ</span><span class="err">）</span><span class="p">:</span>

  <span class="mf">1.</span> <span class="n">エディタを開く</span><span class="p">:</span> <span class="n">https</span><span class="p">:</span><span class="c1">//script.google.com/d/1KEWgIql-gqTNI_Tv_w2-5t7VE_R0eBtjAtd3iqLqabYLOnzJZ8Ga8N4s/edit</span>
  <span class="mf">2.</span> <span class="n">右上の</span><span class="err">「</span><span class="n">部署</span> <span class="o">/</span> <span class="n">Deploy</span><span class="err">」→「</span><span class="n">管理部署作業</span> <span class="o">/</span> <span class="n">Manage</span> <span class="n">deployments</span><span class="err">」</span>
  <span class="mf">3.</span> <span class="n">既存の両方のデプロイ</span><span class="err">（</span><span class="o">@</span><span class="n">HEAD</span> <span class="n">と</span> <span class="n">dev</span> <span class="n">v1</span> <span class="err">—</span> <span class="n">鉛筆アイコンの編集ではアクセス権の変更不可</span><span class="err">）</span><span class="n">を削除</span>
  <span class="mf">4.</span> <span class="n">その後</span><span class="err">、「</span><span class="n">新增部署</span> <span class="o">/</span> <span class="n">New</span> <span class="n">deployment</span><span class="err">」→</span> <span class="n">種類</span><span class="p">:</span> <span class="n">ウェブアプリ</span> <span class="err">→</span> <span class="n">実行者</span><span class="p">:</span> <span class="n">自分</span><span class="err">（</span><span class="n">あなたのアカウント</span><span class="err">）→</span> <span class="n">誰がアクセス可能か</span><span class="p">:</span> <span class="n">だれでも</span> <span class="o">/</span> <span class="n">Anyone</span> <span class="err">→</span> <span class="n">デプロイ</span>
  <span class="mf">5.</span> <span class="n">同意画面でOAuthを許可</span><span class="err">（</span><span class="n">calendar</span><span class="py">.readonly</span><span class="p">,</span> <span class="n">spreadsheets</span><span class="py">.readonly</span><span class="p">,</span> <span class="n">external_request</span><span class="err">）</span>
  <span class="mf">6.</span> <span class="n">新しいウェブアプリのURL</span><span class="err">（</span><span class="n">https</span><span class="p">:</span><span class="c1">//script.google.com/macros/s/AKfycb.../exec のようなもの）をコピーしてここに貼り付ける</span>

  <span class="n">また以下も貼り付けてください</span><span class="p">:</span>
  <span class="o">-</span> <span class="n">CWA</span> <span class="n">APIキー</span><span class="err">（</span><span class="n">交通部中央気象署</span> <span class="n">Open</span> <span class="n">Data</span> <span class="n">Authorization</span><span class="err">）</span>
  <span class="o">-</span> <span class="n">倒數日シートID</span><span class="err">（</span><span class="n">Sheet</span> <span class="n">URLの</span> <span class="o">/</span><span class="n">d</span><span class="o">/</span> <span class="n">と</span> <span class="o">/</span><span class="n">edit</span> <span class="n">の間の長い部分</span><span class="err">）</span>
  <span class="o">-</span> <span class="n">シートGID</span><span class="err">（</span><span class="n">URLの</span> <span class="n">gid</span><span class="o">=</span> <span class="n">の後の数字</span> <span class="err">—</span> <span class="n">最初のタブはデフォルトで0</span><span class="err">）</span>

  <span class="n">URLと秘密情報を受け取ったら</span><span class="err">、</span><span class="n">devエンドポイント経由でPropertiesをセットし</span><span class="err">、</span><span class="n">アクセストークンを発行し</span><span class="err">、</span><span class="n">各ハンドラーを確認して接続します</span><span class="err">。</span>
</code></pre></div></div>

<p>(1.) 初回実行時は認証が必要で、その後はAIエージェントが自動で実行できます。Script EditorのURLへアクセスしてください：</p>

<p><img src="/assets/35cc65327d28/1*qif-nDDBfttn-y6kR2I2VA.webp" alt="" loading="lazy" decoding="async" width="863" height="404" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjMiIGhlaWdodD0iNDA0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/35cc65327d28/1*qif-nDDBfttn-y6kR2I2VA.png" /></p>

<p>適当な関数があるファイルを選び、デバッグしたい関数を選択してください：</p>

<p><img src="/assets/35cc65327d28/1*BgTkreP26mNx7nu9gkhedA.webp" alt="" loading="lazy" decoding="async" width="1412" height="769" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDEyIiBoZWlnaHQ9Ijc2OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*BgTkreP26mNx7nu9gkhedA.png" /></p>

<ul>
  <li>初回実行時または権限を追加した場合にのみ認証が必要です。</li>
</ul>

<blockquote>
  <p><em>もしAIがずっと権限の問題を言っているのに、実際の実行で認証ウィンドウが表示されない場合は、プロジェクト設定で「エディタに『appsscript.json』マニフェストファイルを表示する」をチェックし、エディタに戻って <code class="language-plaintext highlighter-rouge">appsscript.json</code> の <code class="language-plaintext highlighter-rouge">oauthScopes</code> の内容を少し変更して一度実行し、再び元に戻して実行すると認証プロセスが表示されるはずです。</em></p>
</blockquote>

<p><strong>1だけ自分で処理すれば、あとはAIに任せられる:</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">1. OK、直接デプロイしてください</span>
  <span class="s">CWA API Key</span><span class="err">:</span> <span class="s">CWA-XXXX-XXXX-XXXX-XXXX-XXXX</span>
  <span class="s">カウントダウン日 Sheet ID</span><span class="na">: XXXX / GID</span><span class="pi">:</span> <span class="m">0</span>
</code></pre></div></div>

<p><img src="/assets/35cc65327d28/1*E1UAPVqKXjYtmAsJRRABdw.webp" alt="" loading="lazy" decoding="async" width="1266" height="577" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjY2IiBoZWlnaHQ9IjU3NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*E1UAPVqKXjYtmAsJRRABdw.png" /></p>

<p><strong>AIによるGoogle Apps Scriptの設定支援..</strong></p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">⏺</span> <span class="n">スコープが更新されてプッシュされましたが</span><span class="err">、</span><span class="n">デプロイヤーのOAuth許可を新しいスコープに対して再認証する必要があります</span><span class="err">。</span><span class="n">ウェブアプリはあなたのアカウントで実行されます</span> <span class="err">—</span> <span class="n">新たに追加されたスコープは再許可が必要です</span><span class="err">。</span>

  <span class="n">これを一度行ってください</span><span class="err">：</span>

  <span class="mf">1.</span> <span class="n">エディタを開く</span><span class="err">：</span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">script</span><span class="p">.</span><span class="n">google</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">d</span><span class="o">/</span><span class="mi">1</span><span class="n">KEWgIql</span><span class="o">-</span><span class="n">gqTNI_Tv_w2</span><span class="o">-</span><span class="mi">5</span><span class="n">t7VE_R0eBtjAtd3iqLqabYLOnzJZ8Ga8N4s</span><span class="o">/</span><span class="n">edit</span>
  <span class="mf">2.</span> <span class="n">上部の関数ドロップダウンから</span> <span class="n">setupConfig</span><span class="err">（</span><span class="n">または任意の関数</span><span class="err">）</span><span class="n">を選択</span>
  <span class="mf">3.</span> <span class="err">「</span><span class="n">執行</span> <span class="o">/</span> <span class="n">Run</span><span class="err">」</span><span class="n">をクリック</span> <span class="err">—</span> <span class="n">Googleが</span><span class="err">「</span><span class="n">需要授權</span> <span class="o">/</span> <span class="n">Authorization</span> <span class="n">required</span><span class="err">」</span><span class="n">ダイアログを表示します</span>
  <span class="mf">4.</span> <span class="n">許可</span> <span class="err">→</span> <span class="n">アップグレードされたauth</span><span class="o">/</span><span class="n">spreadsheetsスコープを付与</span>
  <span class="mf">5.</span> <span class="n">完了したら教えてください</span><span class="err">。</span><span class="n">カウントダウンハンドラを再テストします</span>
</code></pre></div></div>

<p>私たちはAIと約束していても、時には手動で助けが必要な部分が出てくることがあります。例えば上記のメッセージのように。<strong>私たちは単純に彼の指示通りに関数を一度実行して「OK」と伝えるだけでいいのです。ちょっとした手助けと思ってください。（もし彼の言った方法が表示されなければ、ページをリロードしてください）</strong></p>

<p><img src="/assets/35cc65327d28/1*oLIgKwY7YYbDZszAEMiSKQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="896" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*oLIgKwY7YYbDZszAEMiSKQ.png" /></p>

<h4 id="ai-開発完了検収">AI 開発完了、検収！</h4>

<p><img src="/assets/35cc65327d28/1*_lM4Az2SosWIYlp26KG8zQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="257" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjI1NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*_lM4Az2SosWIYlp26KG8zQ.png" /></p>

<p>問題があれば、AIに修正を依頼してください。</p>

<h3 id="aiで作るあなただけのパーソナルデスクトップダッシュボード--成果">AIで作るあなただけのパーソナルデスクトップダッシュボード — 成果</h3>

<h4 id="デスクトップ版">デスクトップ版</h4>

<p><img src="/assets/35cc65327d28/1*a70ymWexht6E2RLr7v0PWQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="716" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjcxNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*a70ymWexht6E2RLr7v0PWQ.png" /></p>

<h4 id="iphone-モバイル版">iPhone モバイル版</h4>

<p><img src="/assets/35cc65327d28/1*o6rsj5YDo5x47eo4JpvbkQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="675" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY3NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*o6rsj5YDo5x47eo4JpvbkQ.png" /></p>

<blockquote>
  <p><em>GASのWebアプリではフルスクリーンのPWAとしてURLバーを隠すことはできません。100%の体験を求める場合は、上級内容を参照してください。</em></p>
</blockquote>

<h4 id="最終コード">最終コード</h4>

<p><a href="https://github.com/zhgchgli0718/GASDashboardExample" target="_blank"><img src="https://opengraph.githubassets.com/7f1fca54b1504ffaae1102433fb1baff9a4165f507554bb5b745851eefd4eb27/zhgchgli0718/GASDashboardExample" alt="" /></a></p>

<h4 id="今後のタスク">今後のタスク</h4>

<ul>
  <li>
    <p>[required] AIに伝える：開発完了後、すべての開発段階のインターフェース／エンドポイントを削除してください</p>
  </li>
  <li>
    <p>[optional] Google Apps Script プロジェクト -&gt; プロジェクト設定 -&gt; スクリプトプロパティ -&gt; <code class="language-plaintext highlighter-rouge">ACCESS_TOKEN</code> -&gt; 新しいランダム文字列を生成し、URLの <code class="language-plaintext highlighter-rouge">?token=</code> もこの文字列に変更する<br />
macOS では以下のコマンドでランダム文字列を生成できます: <code class="language-plaintext highlighter-rouge">openssl rand -hex 32</code></p>
  </li>
  <li>
    <p>[optional] <a href="https://opendata.cwa.gov.tw/userLogin" target="_blank">交通部中央気象局APIキーの再発行</a> を行い、Google Apps Script プロジェクト -&gt; プロジェクト設定 -&gt; スクリプトのプロパティ -&gt; <code class="language-plaintext highlighter-rouge">CWA_API_KEY</code> に入力してください。</p>
  </li>
</ul>

<blockquote>
  <p><strong><em>⚠️Claude Codeの警告によると：</em></strong> <em>会話内容に露出したすべてのトークンは漏洩したとみなす必要がありますが、開発の便宜上、検証のために一時的に直接入力しています。検証が完了したら、新しいトークンを生成して差し替えてください。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>もしGASに慣れているなら、最初にスクリプトプロパティを設定しておき、AIにそのまま使うよう指示しても良いです。</em></strong></p>
</blockquote>

<h4 id="拡張">拡張</h4>

<p>もしこの記事があなたの創造力を刺激したなら、例えばYahoo Financeを連携して注目している株のリアルタイム株価を取得したり、AnalyticsDataやAdSenseを連携してウェブサイトのトラフィックや広告状況を取得したりすることも考えてみてください。</p>

<h4 id="上級">上級</h4>

<p>GAS Web App は真のRWDや全画面PWA（アドレスバー非表示）を実現できないため、私はGAS Web AppをAPIサービスとしてJSONデータのみ返すようにし、フロントエンド機能は別途GitHub Pagesで実装して正式なウェブページとしてデプロイしています。これにより、完全な使用体験を得られます。</p>

<p><img src="/assets/35cc65327d28/1*Cx-dFPrSRjj8g2tL5Z_kJw.webp" alt="" loading="lazy" decoding="async" width="1160" height="695" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTYwIiBoZWlnaHQ9IjY5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*Cx-dFPrSRjj8g2tL5Z_kJw.png" /></p>

<p><img src="/assets/35cc65327d28/1*vtT3UhsGwmx15v4vNYS4vw.webp" alt="iOS フルスクリーン PWA 設定 -&gt; Safari でURLを開く -&gt; 共有 -&gt; ホーム画面に追加" loading="lazy" decoding="async" width="1200" height="675" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY3NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/35cc65327d28/1*vtT3UhsGwmx15v4vNYS4vw.jpeg" /></p>

<p>iOS フルスクリーン PWA 設定 -&gt; Safari でURLを開く -&gt; 共有 -&gt; ホーム画面に追加</p>

<p><strong>この方法は少し複雑ですが、/plan フェーズでAIにこう伝えることができます:</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- GAS Web App はバックエンドサービスのみを行い、JSON をフロントエンドに出力する
- フロントエンドは GitHub Pages を使ってデザイン表示とデプロイを行い、すべてのプログラム開発とデプロイ作業を担当する
- フロントエンドとバックエンド間はカスタム乱数文字列のトークンで保護する
</code></pre></div></div>

<h3 id="まとめ">まとめ</h3>

<p>以上が今回の AI Agent を使った Google Apps Script 開発体験の紹介です。最近は AI を使って以前開発した中〜大規模の GAS プロジェクトをリファクタリングしており、効果は良好です。<strong>さらにローカルで関数の単体テスト（Jest や Google APIs のモックを使用）を追加して安定性を向上させることも可能です</strong>（CI/CD 環境で実行し、clasp pull と GAS プロジェクトのバックアップと連携）。AI の GAS に対する理解度と出力の正確性はほぼ 100% に近いです。</p>

<h4 id="もし2021年なら">もし2021年なら…</h4>

<p>もしAIがなかった時代なら、デザインからコーディング、プログラムロジック開発、公開まで手作業で約30時間かかっていたと思います。今ではAIを使えば3時間以内で完了できます。</p>

<blockquote>
  <p>基本的に今後はもうGASを一から開発することも、AIにゼロからプログラムを書かせることもせず、AIにゼロから製品を作らせるだけです（プログラム？気にしません）。</p>
</blockquote>

<h4 id="ケース2--個人株式保有リスト管理">ケース(2) — 個人株式保有リスト管理</h4>

<p><img src="/assets/35cc65327d28/1*ouM-S6-JDJ8ddoUDVh8TVg.webp" alt="" loading="lazy" decoding="async" width="1147" height="1295" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQ3IiBoZWlnaHQ9IjEyOTUiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/35cc65327d28/1*ouM-S6-JDJ8ddoUDVh8TVg.png" /></p>

<p>最近試したもう一つのAIによるGoogle Apps Scriptの事例です。私のGoogle Sheetの保有株表を可視化したWebアプリに変換し、Yahoo Financeと連携して最新の株価を取得し表で表示します。下部には売買記録を素早く入力できる欄もあり、入力内容はGoogle Sheetに書き戻されます。</p>

<h4 id="さらなる読書">さらなる読書</h4>

<blockquote>
  <p><em>TL;DR これらは以前に手動で作成したGASサービスとツールです</em></p>
</blockquote>

<ul>
  <li>
    <p><a href="https://medium.com/zrealm-robotic-process-automation/%E4%BD%BF%E7%94%A8-google-apps-script-%E5%AF%A6%E7%8F%BE-google-%E6%9C%8D%E5%8B%99-rpa-%E8%87%AA%E5%8B%95%E5%8C%96-f6713ba3fee3?source=collection_home---6------3-----------------------" target="_blank"><strong>Google Apps Scriptを使った毎日のデータレポートRPA自動化の実現</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-script-firebase-app-distribution-apiとの高速連携方法-効率的なgoogle-apis統合-71400d408dc8/"><strong>Google Apps Script x Google APIs 迅速な連携統合方法</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/"><strong>Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージツールプラットフォームを構築する</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティック-プロセス-オートメーション/ga4自動数値通知ロボット-無料で作る3ステップ-google-apps-scriptとtelegram-bot連携-1e85b8df2348/">簡単3ステップ — 無料GA4自動データ通知ロボットの作成</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-scriptでgmailをslackに自動転送-フィルター連携で効率化-d414bdbdb8c9/">Google Apps Scriptを使ってGmailのメールをSlackに転送する</a></p>
  </li>
  <li>
    <p><a href="https://medium.com/zrealm-robotic-process-automation/slack-%E6%89%93%E9%80%A0%E5%85%A8%E8%87%AA%E5%8B%95-wfh-%E5%93%A1%E5%B7%A5%E5%81%A5%E5%BA%B7%E7%8B%80%E6%B3%81%E5%9B%9E%E5%A0%B1%E7%B3%BB%E7%B5%B1-d61062833c1a?source=collection_home---6------9-----------------------" target="_blank">Slack が作る完全自動 WFH 従業員健康状況報告システム</a></p>
  </li>
  <li>
    <p><a href="https://medium.com/zrealm-robotic-process-automation/crashlytics-big-query-%E6%89%93%E9%80%A0%E6%9B%B4%E5%8D%B3%E6%99%82%E4%BE%BF%E5%88%A9%E7%9A%84-crash-%E8%BF%BD%E8%B9%A4%E5%B7%A5%E5%85%B7-e77b80cc6f89?source=collection_home---6------7-----------------------" target="_blank">Crashlytics + Big Query でよりリアルタイムで便利なクラッシュ追跡ツールを作る</a></p>
  </li>
  <li>
    <p><a href="https://medium.com/zrealm-robotic-process-automation/crashlytics-google-analytics-%E8%87%AA%E5%8B%95%E6%9F%A5%E8%A9%A2-app-crash-free-users-rate-793cb8f89b72?source=collection_home---6------6-----------------------" target="_blank">Crashlytics + Google Analytics 自動で App クラッシュフリー ユーザー率を照会</a></p>
  </li>
  <li>
    <p><a href="https://medium.com/zrealm-robotic-process-automation/%E4%BD%BF%E7%94%A8-google-apps-script-%E4%B8%89%E6%AD%A5%E9%A9%9F%E5%85%8D%E8%B2%BB%E5%BB%BA%E7%AB%8B-github-repo-star-notifier-382218e15697?source=collection_home---6------5-----------------------" target="_blank">Google Apps Script を使って3ステップで無料で GitHub Repo Star Notifier を作成する</a></p>
  </li>
  <li>
    <p><a href="https://medium.com/zrealm-robotic-process-automation/10-%E5%88%86%E9%90%98%E5%BF%AB%E9%80%9F%E7%A7%BB%E8%BD%89-line-notify-%E5%88%B0-telegram-bot-%E9%80%9A%E7%9F%A5-6922e90ba90c?source=collection_home---6------0-----------------------" target="_blank">10分で簡単移行 Line Notify から Telegram Bot 通知へ</a></p>
  </li>
</ul>

<p><em><a href="https://medium.com/zrealm-ios-dev/%E5%88%A5%E5%86%8D%E5%BE%9E%E9%9B%B6%E9%96%8B%E5%A7%8B-ai-%E5%AF%AB%E7%A8%8B%E5%BC%8F-%E8%AE%93-ai-agent-%E7%9B%B4%E6%8E%A5%E5%B9%AB%E4%BD%A0%E6%90%9E%E5%AE%9A-google-apps-script-%E4%B8%B2%E6%8E%A5%E8%88%87%E9%96%8B%E7%99%BC-35cc65327d28" target="_blank">Post</a> Mediumから変換 by <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>.</em></p>]]></content>
  </entry><entry>
    <title type="html">Claude Design｜Claude Codeで週末午後に作るオリジナルJekyllブログテーマ</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-%E9%96%8B%E7%99%BA/claude-design-claude-code%E3%81%A7%E9%80%B1%E6%9C%AB%E5%8D%88%E5%BE%8C%E3%81%AB%E4%BD%9C%E3%82%8B%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%8A%E3%83%ABjekyll%E3%83%96%E3%83%AD%E3%82%B0%E3%83%86%E3%83%BC%E3%83%9E-6bf79c5b4dab/" rel="alternate" type="text/html" title="Claude Design｜Claude Codeで週末午後に作るオリジナルJekyllブログテーマ" />
    <published>2026-04-27T23:00:32+08:00</published>
    <updated>2026-05-06T22:40:53+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-%E9%96%8B%E7%99%BA/6bf79c5b4dab</id><summary type="html">Claude DesignとClaude Codeを使って、自分だけのJekyllブログテーマを簡単に作成。初心者でも短時間で個性的なブログデザインを実現し、発信力を高める方法を紹介します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm 開発" /><category term="クロードコード" /><category term="ギットハブページズ" /><category term="ジェキル" /><category term="ai" /><category term="ブログ" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/6bf79c5b4dab/1*cQbgChJysDv6MjvNic7Hlw.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-%E9%96%8B%E7%99%BA/claude-design-claude-code%E3%81%A7%E9%80%B1%E6%9C%AB%E5%8D%88%E5%BE%8C%E3%81%AB%E4%BD%9C%E3%82%8B%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%8A%E3%83%ABjekyll%E3%83%96%E3%83%AD%E3%82%B0%E3%83%86%E3%83%BC%E3%83%9E-6bf79c5b4dab/"><![CDATA[<h3 id="週末の午後--claude-design--claude-code--あなたのスタイルのブログを作る">週末の午後 + Claude Design + Claude Code = あなたのスタイルのブログを作る</h3>

<p>Claude Design + Claude Code を使って、あなた専用の Jekyll テーマブログを作ろう</p>

<h4 id="httpszhgchgli-20"><a href="https://zhgchg.li/" target="_blank">https://zhgchg.li/</a> 2.0!</h4>

<p><img src="/assets/6bf79c5b4dab/1*cQbgChJysDv6MjvNic7Hlw.webp" alt="&lt;https://zhgchg.li/&gt;" loading="lazy" decoding="async" width="1200" height="1057" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwNTciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/6bf79c5b4dab/1*cQbgChJysDv6MjvNic7Hlw.png" /></p>

<p><a href="https://zhgchg.li/" target="_blank">https://zhgchg.li/</a></p>

<blockquote>
  <p><em>週末の午後を利用して、Claude Design で好みのブログのスタイルと機能を設計し、Claude Code を使って実装し、Jekyll ブログに適用しました。5年間使っていた Chirpy Theme のインターフェースを理想の個人ブログスタイルに完全に置き換えました。</em></p>
</blockquote>

<h4 id="技術">技術</h4>

<ul>
  <li>
    <p><strong>ブログ構成:</strong> Jekyll 静的サイト</p>
  </li>
  <li>
    <p><strong>記事の元ファイル:</strong> Markdown ファイル</p>
  </li>
  <li>
    <p><strong>サーバー／ウェブホスティング:</strong> GitHub Pages（無料で信頼性あり）</p>
  </li>
  <li>
    <p><strong>エンジニアリング:</strong> Claude Code Max（100 USD、5時間のクレジット <strong>使い切る前に完成しました</strong>）</p>
  </li>
  <li>
    <p><strong>デザイン:</strong> Claude Design（ブログページが少ないため、2時間の使用時間で十分です）</p>
  </li>
</ul>

<h4 id="費用">費用</h4>

<ul>
  <li>
    <p>Claude Code Max $100 USD</p>
  </li>
  <li>
    <p>サーバー／ウェブホスティング：$0 USD</p>
  </li>
  <li>
    <p>Jekyll テーマ：0 USD</p>
  </li>
  <li>
    <p>時間：週末の午後</p>
  </li>
</ul>

<h3 id="実現手順">実現手順</h3>

<h4 id="1-ローカルにクリーンな-jekyll-ブログを作成する">1. ローカルにクリーンな Jekyll ブログを作成する</h4>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jekyll new blog
</code></pre></div></div>

<h4 id="2-テーマのページ例を収集して-claude-design-にアップロードする">2. テーマのページ例を収集して Claude Design にアップロードする</h4>

<h4 id="20260506-アップデート-21-design-agent-スキルでサードパーティのデザインスキルを使いデザインを完成させる">[2026/05/06 アップデート] <a href="https://zhgchg.li/posts/zrealm-dev/%E5%88%A5%E5%86%8D%E5%BE%9E%E9%9B%B6%E9%96%8B%E5%A7%8B-ai-%E5%AF%AB%E7%A8%8B%E5%BC%8F-%E8%AE%93-ai-agent-%E7%9B%B4%E6%8E%A5%E5%B9%AB%E4%BD%A0%E6%90%9E%E5%AE%9A-google-apps-script-%E4%B8%B2%E6%8E%A5%E8%88%87%E9%96%8B%E7%99%BC-35cc65327d28/#%E4%BD%BF%E7%94%A8-claude-design-or-design-agent-skill-%E8%A8%AD%E8%A8%88-dashboard" target="_blank">2–1 Design Agent スキルでサードパーティのデザインスキルを使いデザインを完成させる</a></h4>

<p>細かい内容はこの記事「 <a href="https://zhgchg.li/posts/zrealm-dev/%E5%88%A5%E5%86%8D%E5%BE%9E%E9%9B%B6%E9%96%8B%E5%A7%8B-ai-%E5%AF%AB%E7%A8%8B%E5%BC%8F-%E8%AE%93-ai-agent-%E7%9B%B4%E6%8E%A5%E5%B9%AB%E4%BD%A0%E6%90%9E%E5%AE%9A-google-apps-script-%E4%B8%B2%E6%8E%A5%E8%88%87%E9%96%8B%E7%99%BC-35cc65327d28/#%E4%BD%BF%E7%94%A8-claude-design-or-design-agent-skill-%E8%A8%AD%E8%A8%88-dashboard" target="_blank">別再從零開始 AI 寫程式：讓 AI Agent 直接幫你搞定 Google Apps Script 串接與開發</a> 」をご参照ください。</p>

<h4 id="22-claude-design">2–2 Claude Design</h4>

<p>私は現在のブログに直接アクセスし、各ページで右クリックして「名前を付けて保存」を選択します。例えば、Home、Post、Page、PostList、Archives、Tags…</p>

<p><img src="/assets/6bf79c5b4dab/1*EWBgWOobhy5kFeNPq9-uqQ.webp" alt="" loading="lazy" decoding="async" width="482" height="359" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0ODIiIGhlaWdodD0iMzU5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*EWBgWOobhy5kFeNPq9-uqQ.png" /></p>

<p><strong>Theme フォルダを作成し、すべてのページと付属ファイルをその中に入れます:</strong></p>

<p><img src="/assets/6bf79c5b4dab/1*eo3d-J4ehZpBIZfx4bV4Wg.webp" alt="" loading="lazy" decoding="async" width="253" height="231" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTMiIGhlaWdodD0iMjMxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*eo3d-J4ehZpBIZfx4bV4Wg.png" /></p>

<p><strong><a href="https://claude.ai/design" target="_blank">Claude Design</a> にアクセスしてプロジェクトを作成:</strong></p>

<p><img src="/assets/6bf79c5b4dab/1*AYCu31HSzfOHST8nberNWA.webp" alt="&lt;https://claude.ai/design&gt;" loading="lazy" decoding="async" width="377" height="441" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNzciIGhlaWdodD0iNDQxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*AYCu31HSzfOHST8nberNWA.png" /></p>

<p><a href="https://claude.ai/design" target="_blank">https://claude.ai/design</a></p>

<p><strong>Theme ページのサンプルを Claude Design にアップロードし、「Attach codebase」を選択：</strong></p>

<p><img src="/assets/6bf79c5b4dab/1*1A08G_oNaieGA_8t17xPow.webp" alt="" loading="lazy" decoding="async" width="323" height="340" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMjMiIGhlaWdodD0iMzQwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*1A08G_oNaieGA_8t17xPow.png" /></p>

<p><strong>先ほど整理した Theme ディレクトリを選択:</strong></p>

<p><img src="/assets/6bf79c5b4dab/1*KbXyuIRuWnisFYbtnIUhzg.webp" alt="" loading="lazy" decoding="async" width="998" height="560" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5OTgiIGhlaWdodD0iNTYwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*KbXyuIRuWnisFYbtnIUhzg.png" /></p>

<p><strong>選択が完了したら、Prompt を入力して Claude Design にページのデザインを依頼してください:</strong></p>

<p><img src="/assets/6bf79c5b4dab/1*bvO5_7XHaQSRdjbIcj_QsA.webp" alt="" loading="lazy" decoding="async" width="391" height="153" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzOTEiIGhlaWdodD0iMTUzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*bvO5_7XHaQSRdjbIcj_QsA.png" /></p>

<blockquote>
  <p><em>私のブログを再設計するために、繁体字中国語で私と交流してください。</em></p>
</blockquote>

<h4 id="3-claude-design-を使った再設計">3. Claude Design を使った再設計</h4>

<p>送信後、Claude Design はあなたが望むデザインについて質問します:</p>

<p><img src="/assets/6bf79c5b4dab/1*EvWpwlNUXDcLI5MHUz9Jug.webp" alt="" loading="lazy" decoding="async" width="646" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NDYiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6bf79c5b4dab/1*EvWpwlNUXDcLI5MHUz9Jug.png" /></p>

<ul>
  <li>
    <p>いくつかのビジュアルバリエーションを見たいですか？AIが複数の案を生成して選べます。</p>
  </li>
  <li>
    <p>どの Tweaks をリアルタイムで調整したいですか？右下の Debug ツールにはどの切り替え機能が必要ですか？</p>
  </li>
  <li>
    <p>あとはお好みでご自由に入力してください。</p>
  </li>
</ul>

<h4 id="4-claude-design-クッキング">4. Claude Design クッキング…</h4>

<p><img src="/assets/6bf79c5b4dab/1*pBQcJF9Bim581CsPHGdlxQ.webp" alt="" loading="lazy" decoding="async" width="1109" height="1302" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTA5IiBoZWlnaHQ9IjEzMDIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/6bf79c5b4dab/1*pBQcJF9Bim581CsPHGdlxQ.png" /></p>

<p>約3〜5分で、AIが完全なデザインシステム（.css）を作成し、React.js／HTMLで結果を表示します。</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ブログの再設計が完了し、Blog Redesign.html に保存しました。

デザインシステム

フォント：Noto Serif TC（宋体）+ Inter + JetBrains Mono
色調：暖かい紙のクリーム色 + 赤陶のメインカラー（oklch warm 系）
三つの分類軸線：テクノロジー / 旅行 / シェア、すべて実際の中国語のサンプルコンテンツを使用
二つの方向、合計7つのアートボード（ダブルクリックで全画面プレビュー可能）

方向 A · 雑誌風（Magazine）

ホーム — ヘッダーのタイトル + メインレポート + 3カラムのサブ記事 + 番号付きリスト + ニュースレター
記事ページ — 目次付きの完全な単一記事、ドロップキャップ、イントロ、コードブロック、コメント、関連記事
カテゴリページ — 2×2の大きな画像インデックス
タグページ — 視覚化された棒グラフ統計 + タグクラウド
アーカイブページ — 年別 + 月別のタイムライン
アバウトページ — 個人紹介 + Now セクション + 購読

方向 B · モダンパブリケーション（Substack風）  
ホーム — 大きなHero画像 + カード型グリッド + サイドバー購読ウォール

Tweaks パネル（右下で開く）でリアルタイム切替可能：

タイトルフォント（Noto Serif / 思源宋体）
ワイドレイアウト / 標準レイアウト
メインカラーと紙の色（4つのプリセット配色：赤陶、ダークブルー、ダークグリーン、ワインレッド）
</code></pre></div></div>

<h4 id="5-claude-design-結果の調整">5. Claude Design 結果の調整</h4>

<p><img src="/assets/6bf79c5b4dab/1*fRHChM-U_a_dbtde2NcO3w.webp" alt="" loading="lazy" decoding="async" width="1200" height="769" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc2OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6bf79c5b4dab/1*fRHChM-U_a_dbtde2NcO3w.png" /></p>

<ul>
  <li>
    <p>右下の Tweak をクリックすると、パラメータを素早く調整して結果を確認できます。</p>
  </li>
  <li>
    <p>ページ右上の拡大ボタンをクリックすると、ウェブページ全体を表示できます。インタラクティブ機能がある場合は、モックアップ上で直接操作も可能です。</p>
  </li>
  <li>
    <p>クリックが無効、スクロールできない、ページが正しく表示されない、または内容が切れている場合は、AIに調整を依頼できます。</p>
  </li>
</ul>

<p>AI と引き続き対話し、必要な機能を追加したり既存の機能を調整したりできます。例えば、記事の末尾に buy me a coffee の寄付リンクやコメント欄を追加したい場合、<strong>次のように伝えればよいです：</strong></p>

<p><img src="/assets/6bf79c5b4dab/1*5IdYAz7JCerimasdQQl8lA.webp" alt="" loading="lazy" decoding="async" width="389" height="684" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzODkiIGhlaWdodD0iNjg0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*5IdYAz7JCerimasdQQl8lA.png" /></p>

<p><strong>結果:</strong></p>

<p><img src="/assets/6bf79c5b4dab/1*UdAS4J2B494L3RYk_Dpgcg.webp" alt="" loading="lazy" decoding="async" width="846" height="1184" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NDYiIGhlaWdodD0iMTE4NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6bf79c5b4dab/1*UdAS4J2B494L3RYk_Dpgcg.png" /></p>

<blockquote>
  <p>AIと対話を続けて、機能やページデザインを自分好みに作り上げる。</p>
</blockquote>

<h4 id="6-claude-design-完了">6. Claude Design 完了</h4>

<p>デザインに満足したら、右上の「Share」→「Download project as .zip」をクリックして、元のデザインファイルをダウンロードします:</p>

<p><img src="/assets/6bf79c5b4dab/1*HD6TIUrAQXeduhkUoRdC7g.webp" alt="" loading="lazy" decoding="async" width="477" height="450" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NzciIGhlaWdodD0iNDUwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*HD6TIUrAQXeduhkUoRdC7g.png" /></p>

<p>ダウンロードして解凍後、フォルダを Jekyll Blog のディレクトリに配置します:</p>

<p><img src="/assets/6bf79c5b4dab/1*ZUZcFtumkmeo9UuTACQakw.webp" alt="" loading="lazy" decoding="async" width="326" height="476" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMjYiIGhlaWdodD0iNDc2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*ZUZcFtumkmeo9UuTACQakw.png" /></p>

<h4 id="7-claude-code-に-claude-design-のデザイン案を実装してもらう">7. Claude Code に Claude Design のデザイン案を実装してもらう</h4>

<p><img src="/assets/6bf79c5b4dab/1*npQOf0QkzG6qDJKwT1-f9A.webp" alt="" loading="lazy" decoding="async" width="1078" height="725" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDc4IiBoZWlnaHQ9IjcyNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6bf79c5b4dab/1*npQOf0QkzG6qDJKwT1-f9A.png" /></p>

<p>Jekyll Blog のディレクトリで一度 <code class="language-plaintext highlighter-rouge">/init</code> を実行し、AI にこれが Jekyll Blog の構造であることを認識させてください。</p>

<p><img src="/assets/6bf79c5b4dab/1*sEtu11Zbw5ZkP5n69uyVmA.webp" alt="" loading="lazy" decoding="async" width="668" height="217" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NjgiIGhlaWdodD0iMjE3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*sEtu11Zbw5ZkP5n69uyVmA.png" /></p>

<blockquote>
  <p><em>./MyBlogTheme のテーマデザインを私のブログに適用する</em></p>
</blockquote>

<h4 id="8-claude-code-のビルド">8. Claude Code のビルド…</h4>

<p><img src="/assets/6bf79c5b4dab/1*_iSl56RBPuHX9OqAjR4q-g.webp" alt="" loading="lazy" decoding="async" width="1192" height="1174" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTkyIiBoZWlnaHQ9IjExNzQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/6bf79c5b4dab/1*_iSl56RBPuHX9OqAjR4q-g.png" /></p>

<p><img src="/assets/6bf79c5b4dab/1*D8RjjpPikNWEqe2G55PkhA.webp" alt="" loading="lazy" decoding="async" width="1192" height="1174" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTkyIiBoZWlnaHQ9IjExNzQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/6bf79c5b4dab/1*D8RjjpPikNWEqe2G55PkhA.png" /></p>

<ul>
  <li>初回の構築には約 20K トークン（Opus 4.7 / 努力度：中程度）がかかりました</li>
</ul>

<h4 id="成果">成果：</h4>

<p><code class="language-plaintext highlighter-rouge">bundle exec jekyll serve</code> を実行し、http://127.0.0.1:4000/ を開いて結果を確認します:</p>

<p><img src="/assets/6bf79c5b4dab/1*nvsTfFy1S2siBrAlHcbguQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="638" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjYzOCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6bf79c5b4dab/1*nvsTfFy1S2siBrAlHcbguQ.png" /></p>

<blockquote>
  <p>引き続き AI による最適化と問題修正を行いますが、基本的な完成度はすでに非常に高いです！</p>
</blockquote>

<h3 id="実現の小さなコツ">実現の小さなコツ</h3>

<ul>
  <li>
    <p>AIに「あなたのブログは GitHub Pages」や他のプラットフォームにデプロイされると伝えてください。プラットフォームごとに機能が異なる場合があります。例えば、GitHub Pages は一部の<a href="https://github.com/github/pages-gem/blob/master/lib/github-pages/plugins.rb#L21-L42" target="_blank">Jekyll Plugins</a>のみを許可しており、許可リストにないプラグインは公開後に使用できません。</p>
  </li>
  <li>
    <p>AIにこう伝えてください： <code class="language-plaintext highlighter-rouge">優先的に Jekyll ネイティブ、Jekyll プラグイン、無料オープンソースのプロジェクトを使って機能を実装する。</code></p>
  </li>
  <li>
    <p>AIにこう伝えてください：<code class="language-plaintext highlighter-rouge">ウェブサイト設計では必ずSEO構造とRWDの操作体験を重視してください。</code></p>
  </li>
  <li>
    <p>AIにこう伝えてください：<code class="language-plaintext highlighter-rouge">既存のテーマを新しいテーマに置き換える</code>。</p>
  </li>
  <li>
    <p>GitHub Pages にデプロイするための CI/CD 用 YAML も AI に書かせることができ、手順も教えてくれます。</p>
  </li>
  <li>
    <p><strong>新しいページデザインを調整したい場合は、Claude Design に戻ってデザインを修正し、調整後に再ダウンロードしてディレクトリに戻すことをお勧めします。Claude Code に直接ビジュアルデザインを依頼するのはあまり得意ではないため推奨しません。</strong></p>
  </li>
</ul>

<h4 id="私が使用したパッケージや機能"><strong>私が使用したパッケージや機能</strong></h4>

<p><strong>Jekyll パッケージ:</strong></p>

<ul>
  <li>
    <p>jekyll 4.3 + kramdown (GFM) + kramdown-parser-gfm</p>
  </li>
  <li>
    <p>rouge — コードのシンタックスハイライト</p>
  </li>
  <li>
    <p>jekyll-feed — Atomフィード (/feed.xml)</p>
  </li>
  <li>
    <p>jekyll-sitemap — /sitemap.xml</p>
  </li>
  <li>
    <p>jekyll-paginate-v2 — 記事のページネーション機能</p>
  </li>
  <li>
    <p>jekyll-archives — アーカイブページ</p>
  </li>
  <li>
    <p>jekyll-seo-tag — SEOメタタグ / OG / Twitterカードメタ</p>
  </li>
  <li>
    <p>jekyll-redirect-from — 短縮URLのリダイレクト</p>
  </li>
</ul>

<p><strong>CSS / フロントエンドリソース:</strong></p>

<ul>
  <li>
    <p>GLightbox v3（CDN, MIT） — 画像クリックで拡大するライトボックス</p>
  </li>
  <li>
    <p>SCSS：assets/css/main.scss</p>
  </li>
  <li>
    <p><a href="https://fontawesome.com/" target="_blank">Font Awesome</a> アイコン SVG</p>
  </li>
</ul>

<p><strong>JavaScript 機能:</strong></p>

<ul>
  <li>
    <p>ドロワーメニュー（トップバーメニュー / オーバーレイ / ESCキーで閉じる）</p>
  </li>
  <li>
    <p>LQIP ハイドレーター＆レイジーロード — 記事画像のプレースホルダー＆遅延読み込み</p>
  </li>
  <li>
    <p>読書進捗バー</p>
  </li>
  <li>
    <p>クライアントサイドの目次</p>
  </li>
  <li>
    <p>Search：/search.json をビルド時に生成 + 純粋な JS サブストリングフィルター（lunr 不使用）</p>
  </li>
</ul>

<p><strong>サードパーティサービス:</strong></p>

<ul>
  <li>giscus — コメント（GitHub Discussions）</li>
</ul>

<h3 id="背景">背景</h3>

<p>2018年からMediumでプログラムと生活についての記事を書き始め、後に自作ツールの<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>を開発しました。これはMediumの記事をダウンロードしてMarkdownファイルに変換しバックアップするもので、併せてJekyll + Chirpyテーマで独立したブログサイトを作り、無料のGitHub Pages上にデプロイしています。</p>

<p><a href="https://github.com/jekyll/jekyll" target="_blank"><img src="https://repository-images.githubusercontent.com/65252/f2b7c780-70b6-11e9-85d2-f4bda8708a2d" alt="" /></a></p>

<p>Jekyll は便利な静的サイトジェネレーターで、Markdown とテンプレートを HTML に変換し、その HTML ファイルをホスティングサービスにアップロードすることで、コンテンツを公開できます。</p>

<ul>
  <li>
    <p>私も Jekyll を使って自分の Linktree を作りました: <a href="https://link.zhgchg.li" target="_blank">https://link.zhgchg.li</a></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">jekyll new blog</code> でデフォルトのブログプロジェクトを素早く作成できます</p>
  </li>
</ul>

<p><strong>Jekyll のデフォルトのブログプロジェクトスタイルは非常にシンプルです:</strong></p>

<p><img src="/assets/6bf79c5b4dab/1*SB1pZSaMsMvUG8AiUla62w.webp" alt="" loading="lazy" decoding="async" width="792" height="937" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3OTIiIGhlaWdodD0iOTM3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6bf79c5b4dab/1*SB1pZSaMsMvUG8AiUla62w.png" /></p>

<p>しかし、満足のいく Jekyll Blog テーマを見つけるのは簡単ではありません。ホームページは綺麗でも、記事内容ページの使い勝手が良いものや、一覧ページが優れているものもあります。有料テーマでも完全に満足できるものはなかなか見つかりません。また、インストールして設定を終えた後に機能やページが足りないことに気づき、また探し直さなければならないこともあり、とても大変です。</p>

<p><a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank"><img src="https://repository-images.githubusercontent.com/165360641/257ebaa6-61dd-40a4-b075-d21b546026d6" alt="" /></a></p>

<p><strong>何度も探し回った結果、レイアウトが良く、RWD対応でブログ機能が充実したテーマ — <a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Theme Chirpy</a> — を見つけました：</strong></p>

<p><img src="/assets/6bf79c5b4dab/1*Ayc3pF9qbahE5U2BnzixaQ.webp" alt="Live Demo" loading="lazy" decoding="async" width="1576" height="1143" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTc2IiBoZWlnaHQ9IjExNDMiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/6bf79c5b4dab/1*Ayc3pF9qbahE5U2BnzixaQ.png" /></p>

<p><a href="https://chirpy.cotes.page/posts/text-and-typography/" target="_blank">Live Demo</a></p>

<p>5年間ずっと使い続けており、飽きて乗り換えたい時期もありました。しかし、何度も迷った末に結局は<a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank"><strong>Theme Chirpy</strong></a>に戻ってきました。前述の通り、これ以上見た目も機能も優れたテーマは見つかりませんでした。</p>

<blockquote>
  <p>Claude Design + Claude Code が登場するまでは、一気にAIに頼んで自分の望むブログのスタイルをデザインし、機能ページを実装することはありませんでした。</p>
</blockquote>

<p><em><a href="https://medium.com/zrealm-ios-dev/%E4%B8%80%E5%80%8B%E9%80%B1%E6%9C%AB%E5%8D%88%E5%BE%8C-claude-design-claude-code-%E6%89%93%E9%80%A0%E5%B1%AC%E6%96%BC%E4%BD%A0%E8%87%AA%E5%B7%B1%E9%A2%A8%E6%A0%BC%E7%9A%84-blog-6bf79c5b4dab" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>を使って変換しました。</em></p>]]></content>
  </entry><entry>
    <title type="html">北海道札幌6日遊｜札幌市區散策・定山溪温泉・富良野＆美瑛点灯ツアー完全ガイド</title>
    <link href="https://jp.zhgchg.li/posts/z%E5%BA%A6%E6%97%85%E8%A1%8C%E8%A8%98/%E5%8C%97%E6%B5%B7%E9%81%93%E6%9C%AD%E5%B9%8C6%E6%97%A5%E9%81%8A-%E6%9C%AD%E5%B9%8C%E5%B8%82%E5%8D%80%E6%95%A3%E7%AD%96-%E5%AE%9A%E5%B1%B1%E6%BA%AA%E6%B8%A9%E6%B3%89-%E5%AF%8C%E8%89%AF%E9%87%8E-%E7%BE%8E%E7%91%9B%E7%82%B9%E7%81%AF%E3%83%84%E3%82%A2%E3%83%BC%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-055527a739dd/" rel="alternate" type="text/html" title="北海道札幌6日遊｜札幌市區散策・定山溪温泉・富良野＆美瑛点灯ツアー完全ガイド" />
    <published>2026-04-19T23:51:51+08:00</published>
    <updated>2026-04-20T23:33:43+08:00</updated>
    <id>https://jp.zhgchg.li/posts/z%E5%BA%A6%E6%97%85%E8%A1%8C%E8%A8%98/055527a739dd</id><summary type="html">札幌市内観光と定山溪温泉でリフレッシュ、富良野精霊台＆美瑛青池の幻想的な点灯を満喫したい旅行者向けに、効率的な6日間プランと現地情報を詳しく解説します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="Z度旅行記" /><category term="日本" /><category term="生活" /><category term="旅行" /><category term="旅行記" /><category term="北海道" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/055527a739dd/1*4N6zFGkzcM6QsIulPOwslQ.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/z%E5%BA%A6%E6%97%85%E8%A1%8C%E8%A8%98/%E5%8C%97%E6%B5%B7%E9%81%93%E6%9C%AD%E5%B9%8C6%E6%97%A5%E9%81%8A-%E6%9C%AD%E5%B9%8C%E5%B8%82%E5%8D%80%E6%95%A3%E7%AD%96-%E5%AE%9A%E5%B1%B1%E6%BA%AA%E6%B8%A9%E6%B3%89-%E5%AF%8C%E8%89%AF%E9%87%8E-%E7%BE%8E%E7%91%9B%E7%82%B9%E7%81%AF%E3%83%84%E3%82%A2%E3%83%BC%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-055527a739dd/"><![CDATA[<h3 id="旅行記-2026年北海道札幌6日間の旅--札幌市内定山渓温泉北海道ライトアップ富良野エルフ台美瑛青い池日帰りツアー">[旅行記] 2026年北海道札幌6日間の旅 — 札幌市内、定山渓温泉、北海道ライトアップ（富良野エルフ台＆美瑛青い池）日帰りツアー</h3>

<p>北海道札幌市内散策、定山渓温泉、富良野エルフ台と美瑛青い池ライトアップツアー完全記録</p>

<p><img src="/assets/055527a739dd/1*4N6zFGkzcM6QsIulPOwslQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="760" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc2MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*4N6zFGkzcM6QsIulPOwslQ.png" /></p>

<p>新しい仕事を始めて約半年が経ち、担当していたプロジェクトも終わったので、雪の降る日本には行ったことがなく、3月中旬に北海道旅行に行くことにしました。</p>

<h3 id="出発前の準備">出発前の準備</h3>

<h4 id="計画">計画</h4>

<ul>
  <li>
    <p>第一日目：札幌到着後、直接定山渓温泉へ一泊</p>
  </li>
  <li>
    <p>2日目：札幌市内へ戻り観光</p>
  </li>
  <li>
    <p>第三日目：小樽、小樽水族館</p>
  </li>
  <li>
    <p>第四日目： <a href="https://www.kkday.com/zh-tw/product/157133-hokkaido-sapporo-biei-blue-pond-illumination-tour-japan?cid=19365" target="_blank"><strong>KKday 北海道イルミネーションツアー｜富良野エルフヒル＆美瑛青い池＆白髭の滝日帰りツアー｜札幌発</strong></a></p>
  </li>
  <li>
    <p>第五日目：ショッピングと北海道神宮</p>
  </li>
  <li>
    <p>第6日目：空港へ向かい帰路へ</p>
  </li>
</ul>

<h4 id="行ぎょう">行（ぎょう）</h4>

<h4 id="航空券--チャイナエアライン"><strong>航空券 — チャイナエアライン</strong></h4>

<ul>
  <li>
    <p>🛫 03/15 行き CI130 : TPE 桃園国際空港 T2 <strong>08:35</strong> （実際は3分遅延）-&gt; CTS 北海道新千歳空港 <strong>13:15</strong> （実際は7分遅延）</p>
  </li>
  <li>
    <p>🛬 03/20 帰路 CI131 : CTS 北海道新千歳空港 <strong>14:20</strong> （実際は8分遅延） <strong>-&gt;</strong> TPE 桃園国際空港 <strong>18:15</strong> （実際は3分早着）</p>
  </li>
</ul>

<blockquote>
  <p><em>価格：NT $24,356/人</em></p>
</blockquote>

<blockquote>
  <p>*雪のシーズンがまだ終わっていないため料金が高く、金曜日に帰るのは週末（土日）がさらに高いためです…</p>
</blockquote>

<h4 id="札幌駅---定山渓-往復バスチケット"><strong>札幌駅 &lt;-&gt; 定山渓 往復バスチケット</strong></h4>

<p><img src="/assets/055527a739dd/1*WwGk0L6ccnJi3FweO4qr_g.webp" alt="" loading="lazy" decoding="async" width="848" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NDgiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*WwGk0L6ccnJi3FweO4qr_g.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*i7zUMAOkPm7RwhcYbs3xVA.webp" alt="https://jozankei.jp/tw/news/newaccess/" loading="lazy" decoding="async" width="1200" height="848" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*i7zUMAOkPm7RwhcYbs3xVA.jpeg" /></p>

<p>https://jozankei.jp/tw/news/newaccess/</p>

<p>新千歳空港から札幌駅へのJRは本数が多く、飛行機の到着時間が不確定だったため、事前に切符は購入しませんでした。定山渓温泉へはバスでしか行けません。<a href="https://jozankei.jp/tw/news/newaccess/" target="_blank">2025/12 最新交通情報</a>によると、3つのルートがあります：</p>

<ol>
  <li>
    <p><strong>[予約必須][約60分] 札幌駅 → Kappa Linerバス乗車 → 定山渓温泉。</strong><br />
<strong>時刻表はこちらをクリック</strong></p>
  </li>
  <li>
    <p>[予約不要][約70分] 札幌駅 → 真駒内駅 → バス → 定山渓温泉。</p>
  </li>
  <li>
    <p>[予約不要][約120分] 新千歳空港 → <a href="https://www.hokto.co.jp/makomanai-chitose/" target="_blank">空港バス（北斗交通）</a> → 真駒内駅 → 定山渓温泉。</p>
  </li>
</ol>

<p><strong>ルート(1) — <a href="https://www.jotetsu.co.jp/bus/kappa_liner/index.html" target="_blank">かっぱライナー号 / Kappa Liner</a> は最も便利でスムーズです</strong>。便を調べたところ、飛行機の到着後、入国審査を済ませてJRで札幌駅に出て、午後4時発（秋冬限定便）に十分間に合うので、事前にネットで予約しました（外国人も利用可能です！）。</p>

<p><strong>往路 札幌駅 -&gt; 定山渓：</strong></p>

<p><img src="/assets/055527a739dd/1*cAKpufRPO7_kJuG-f3l74w.webp" alt="&lt;https://www.jotetsu.co.jp/bus/kappa_liner/index.html&gt;" loading="lazy" decoding="async" width="868" height="619" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjgiIGhlaWdodD0iNjE5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*cAKpufRPO7_kJuG-f3l74w.png" /></p>

<p><a href="https://www.jotetsu.co.jp/bus/kappa_liner/index.html" target="_blank">https://www.jotetsu.co.jp/bus/kappa_liner/index.html</a></p>

<ul>
  <li>注意すべきは、<strong>赤字の便は秋冬季のみ運行</strong>であり、札幌駅16:00/17:00発の便は定山渓車庫前までの運行です。</li>
</ul>

<p><strong>帰路 定山渓 -&gt; 札幌駅：</strong></p>

<p><img src="/assets/055527a739dd/1*qVXeuuYsNv__vp_ye6jnvw.webp" alt="&lt;https://www.jotetsu.co.jp/bus/kappa_liner/index.html&gt;" loading="lazy" decoding="async" width="923" height="535" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjMiIGhlaWdodD0iNTM1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*qVXeuuYsNv__vp_ye6jnvw.png" /></p>

<p><a href="https://www.jotetsu.co.jp/bus/kappa_liner/index.html" target="_blank">https://www.jotetsu.co.jp/bus/kappa_liner/index.html</a></p>

<ul>
  <li>帰りは11:00のチェックアウト後に温泉街を散策してから戻る予定だったので、13:15発（白絹の滝 13:31乗車）の便を予約しました。</li>
</ul>

<p><strong>予約方法：</strong></p>

<ol>
  <li><a href="https://jotetsu.quicktrip.jp/buy" target="_blank">公式予約サイト</a>で会員登録をする</li>
</ol>

<p><img src="/assets/055527a739dd/1*CzG4MgskigUp8NXhe3xExw.webp" alt="" loading="lazy" decoding="async" width="767" height="484" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjciIGhlaWdodD0iNDg0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*CzG4MgskigUp8NXhe3xExw.png" /></p>

<ul>
  <li>
    <p>Email / 台湾の携帯番号は問題ありません。</p>
  </li>
  <li>
    <p>必ずアカウントとパスワードを覚えておいてください。電子チケットはオンラインで直接有効化し、運転手に見せて確認してもらいます。</p>
  </li>
</ul>

<p>2.購入するのは <a href="https://jotetsu.quicktrip.jp/buy/reservation?salesTicketId=1943" target="_blank">かっぱライナー号 / Kappa Liner</a> の往復または片道切符</p>

<p><img src="/assets/055527a739dd/1*HjF2Kh18Rm6CxchhV8rP7g.webp" alt="" loading="lazy" decoding="async" width="721" height="187" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MjEiIGhlaWdodD0iMTg3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*HjF2Kh18Rm6CxchhV8rP7g.png" /></p>

<p>3.人数の選択</p>

<p><img src="/assets/055527a739dd/1*BuuwoHzpfc4R2XeDb-0Luw.webp" alt="" loading="lazy" decoding="async" width="745" height="279" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NDUiIGhlaWdodD0iMjc5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*BuuwoHzpfc4R2XeDb-0Luw.png" /></p>

<ol>
  <li>出発日の選択と便の選択（便の時間は札幌発を基準としています）</li>
</ol>

<p><img src="/assets/055527a739dd/1*6JVbtozEiw37fj0EqFDADw.webp" alt="" loading="lazy" decoding="async" width="779" height="1209" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzkiIGhlaWdodD0iMTIwOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*6JVbtozEiw37fj0EqFDADw.png" /></p>

<ol>
  <li>往路の乗降場所を選択</li>
</ol>

<p><img src="/assets/055527a739dd/1*apTSepE2RXgoJmbK_IoFjA.webp" alt="" loading="lazy" decoding="async" width="762" height="486" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjIiIGhlaWdodD0iNDg2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*apTSepE2RXgoJmbK_IoFjA.png" /></p>

<p>乗降車駅は以下の図表を参照してください：</p>

<p><img src="/assets/055527a739dd/1*NyUAFnQb4KqMSoXiRiT6iw.webp" alt="&lt;https://www.jotetsu.co.jp/bus/kappa_liner/index.html&gt;" loading="lazy" decoding="async" width="1200" height="736" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjczNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*NyUAFnQb4KqMSoXiRiT6iw.png" /></p>

<p><a href="https://www.jotetsu.co.jp/bus/kappa_liner/index.html" target="_blank">https://www.jotetsu.co.jp/bus/kappa_liner/index.html</a></p>

<p>私たちのホテルは <strong>(2) <a href="https://jozankei.jp/tw/spot/1449/" target="_blank">白糸の滝/Shiraitonotaki</a></strong> に近いため、この停留所で降りる予約をしました。</p>

<blockquote>
  <p><em>後で気づきましたが、<strong>(7) 定山渓温泉東2丁目 / Jozankei Onsen Higashi 2 Chome</strong>で降りるまで一周乗ってもよく、そこがホテルの目の前です。</em></p>
</blockquote>

<ol>
  <li>
    <p>帰りの日付と便（便の時間は出発地点の時刻で表示）、乗降場所を選択</p>
  </li>
  <li>
    <p>オンラインでクレジットカード決済を完了する</p>
  </li>
</ol>

<blockquote>
  <p><em>価格：大人一人あたり¥2,920。</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*5flfur4c5dHTJsugsXkN0A.webp" alt="" loading="lazy" decoding="async" width="569" height="1013" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjkiIGhlaWdodD0iMTAxMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*5flfur4c5dHTJsugsXkN0A.png" /></p>

<p>予約が成功するとメールで通知が届きます。<strong>チケットの交換は不要で、<a href="https://jotetsu.quicktrip.jp/bought" target="_blank">チケットサイトでオンライン有効化</a>し、そのまま運転手に見せるだけでOKです</strong>。</p>

<h4 id="esim">eSIM</h4>

<p>同じく KKday で購入した5G使い放題のeSIMですが、今回は北海道で美瑛の深い山中で一度だけ電波が届かなかった以外は問題ありませんでした。今回は特にChatGPT対応のプランを選び、情報検索が便利でした。</p>

<ul>
  <li>
    <p>KKday 購入： <a href="https://www.kkday.com/zh-tw/product/137689-japan-unlimited-data-esim-card?cid=19365" target="_blank">日本 eSIM｜Docomo / KDDI / SoftBank / Rakuten｜ <strong>ChatGPT と Gemini 対応</strong></a></p>
  </li>
  <li>
    <p><strong>eSIMはネット環境がある場所で有効化する必要があり、できれば空港で飛行機に乗る前に台湾で有効化するのがベストです</strong></p>
  </li>
</ul>

<blockquote>
  <p><em>価格：NT $343/6日間、無制限データ（フェアユースポリシー適用）</em></p>
</blockquote>

<h4 id="日本を訪れる">日本を訪れる</h4>

<p><a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E4%BA%AC%E9%98%AA%E7%A5%9E%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-%E4%BA%AC%E9%83%BD%E5%A4%A7%E9%98%AA%E7%A5%9E%E6%88%B68%E6%97%A5%E9%81%8A%E5%85%A8%E7%B4%80%E9%8C%84%E8%88%87%E5%AF%A6%E7%94%A8%E4%BA%A4%E9%80%9A%E4%BD%8F%E5%AE%BF%E6%8C%87%E5%8D%97-76d66c2e34af/#20241125-%E6%9B%B4%E6%96%B0%E5%85%A5%E5%A2%83%E5%AF%A9%E6%9F%A5%E8%88%87%E6%B5%B7%E9%97%9C%E7%94%B3%E5%A0%B1qr-code-%E5%B7%B2%E5%90%88%E4%BD%B5%E6%88%90%E5%90%8C%E4%B8%80%E5%80%8B%E5%85%A5%E5%A2%83%E5%AE%A1%E6%9F%A5%E5%8F%8A%E6%B5%B7%E5%85%B3%E7%94%B3%E6%8A%A5%E7%9A%84qr%E7%A0%81%E6%B2%92%E6%9C%89%E8%97%8D%E7%A2%BC%E9%BB%83%E7%A2%BC%E5%8D%80%E5%88%A5%E4%BB%A5%E4%B8%8B%E5%85%A7%E5%AE%B9%E5%8F%AA%E7%95%B6%E7%B4%80%E9%8C%84%E5%8F%AF%E4%BB%A5%E5%BF%BD%E7%95%A5" target="_blank">事前に登録を済ませておけばよく、現在は入国審査と税関審査で同じQRコードを使います。</a></p>

<h3 id="宿泊">宿泊</h3>

<h4 id="031516-1泊--jozankei-yurakusoan-ゆらく草庵-和風温泉旅館"><strong>03/15–16 (1泊) — <a href="https://maps.app.goo.gl/mi1LRdo79NghFL3n7" target="_blank">Jozankei Yurakusoan ゆらく草庵 和風温泉旅館</a></strong></h4>

<p><img src="/assets/055527a739dd/1*NeSAUcKO7d4QbVw6OGaF6A.webp" alt="*北海道札幌市南区定山渓温泉東3条228–1 061–2301 日本*" loading="lazy" decoding="async" width="512" height="362" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iMzYyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*NeSAUcKO7d4QbVw6OGaF6A.png" /></p>

<p><a href="https://maps.app.goo.gl/H3xB8zhQ7vNSeqtaA" target="_blank"><em>北海道札幌市南区定山渓温泉東3条228–1 061–2301 日本</em></a></p>

<p>定山渓温泉街の入口に位置しています。</p>

<blockquote>
  <p><em>価格：¥52,150 — 1泊2名利用/和朝食付き/専用露天風呂あり/禁煙（ハリウッドツインルーム畳付き — 禁煙）</em></p>
</blockquote>

<h4 id="031620-4泊--keio-prelia-hotel-sapporo--京王プレリアホテル札幌--札幌京王プレリアホテル"><strong>03/16–20 (4泊) —</strong> <a href="https://maps.app.goo.gl/agffZjxdVngA5p5B9" target="_blank">Keio Prelia Hotel Sapporo / 京王プレリアホテル札幌 / 札幌京王プレリアホテル</a></h4>

<p><img src="/assets/055527a739dd/1*3oY7bhsG8XdTjJQprMIvhQ.webp" alt="4丁目-11–1 北8条西, 北区, 札幌市, 北海道 060–0808日本" loading="lazy" decoding="async" width="1144" height="832" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQ0IiBoZWlnaHQ9IjgzMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*3oY7bhsG8XdTjJQprMIvhQ.png" /></p>

<p><a href="https://maps.app.goo.gl/yko9ThsVPsdDj4WP6" target="_blank">4丁目-11–1 北8条西, 北区, 札幌市, 北海道 060–0808 日本</a></p>

<p>札幌駅の裏口から徒歩約5分の場所にあります。</p>

<blockquote>
  <p><em>価格：¥58,389 — 4泊快適なキングサイズダブルルーム／禁煙。</em></p>
</blockquote>

<h3 id="楽しみ">楽しみ</h3>

<h4 id="kkday-日帰りツアー北海道ライトアップツアー-富良野エルフヒル美瑛青い池白髭の滝日帰りツアー札幌発"><a href="https://www.kkday.com/zh-tw/product/157133-hokkaido-sapporo-biei-blue-pond-illumination-tour-japan?cid=19365" target="_blank">KKday 日帰りツアー：北海道ライトアップツアー ｜富良野エルフヒル＆美瑛青い池＆白髭の滝日帰りツアー｜札幌発</a></h4>

<p><img src="/assets/055527a739dd/1*5vq3ePeRaN3GcAHfFINuvA.webp" alt="北海道ライトアップツアー ｜富良野エルフヒル＆美瑛青い池＆白髭の滝日帰りツアー｜札幌発" loading="lazy" decoding="async" width="1175" height="1075" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTc1IiBoZWlnaHQ9IjEwNzUiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*5vq3ePeRaN3GcAHfFINuvA.png" /></p>

<p><a href="https://www.kkday.com/zh-tw/product/157133-hokkaido-sapporo-biei-blue-pond-illumination-tour-japan?cid=19365" target="_blank">北海道ライトアップツアー｜富良野エルフヒル＆美瑛青い池＆白髭の滝日帰りツアー｜札幌発</a></p>

<ul>
  <li><strong>[ゆったり11:50出発 Bプラン]</strong> 2026年3月＆4月 \| 昼間は富良野エルフの台＆クリスマスツリー＆白髭の滝＆夜は青い池ライトアップ（四季彩の丘なし）</li>
</ul>

<blockquote>
  <p><em>価格：NT $1,807 台湾ドル／人。</em></p>
</blockquote>

<h4 id="kkday---公式販売北海道小樽水族館入場券購入後すぐに利用可能購入から30日以内に使用可"><a href="https://www.kkday.com/zh-tw/product/139823-otaru-aquarium-admission-ticket-hokkaido?cid=19365" target="_blank">KKday — 【 公式販売】北海道小樽水族館入場券（購入後すぐに利用可能/購入から30日以内に使用可）</a></h4>

<p><img src="/assets/055527a739dd/1*LV2OUgLymbyCMmfLjgsfpg.webp" alt="【公式販売】北海道小樽水族館入場券（購入後すぐ利用可能／購入から30日以内に使用可）" loading="lazy" decoding="async" width="1158" height="939" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTU4IiBoZWlnaHQ9IjkzOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*LV2OUgLymbyCMmfLjgsfpg.png" /></p>

<p><a href="https://www.kkday.com/zh-tw/product/139823-otaru-aquarium-admission-ticket-hokkaido?cid=19365" target="_blank">【公式販売】北海道小樽水族館入場券（購入後すぐ利用可能／購入日から30日以内有効）</a></p>

<ul>
  <li>特徴は屋外の港で飼育されていることで、多くのショーがあり、冬にはペンギンのパレードが開催されることです。</li>
</ul>

<blockquote>
  <p><em>準備！出発！</em></p>
</blockquote>

<blockquote>
  <p><a href="https://calec.china-airlines.com/eCheckin/eCheckin_home.aspx" target="_blank"><em>出発の3日前までに座席指定とオンラインチェックインが可能で、手続きをスムーズにします。</em></a></p>
</blockquote>

<h3 id="day-1-0315-日--北海道札幌到着定山渓温泉ホテル">Day 1 (03/15 日) — 北海道札幌到着、定山渓温泉ホテル</h3>

<h4 id="0500-空港送迎-出発"><a href="https://www.kkday.com/zh-tw/trans/airport_transfer?cid=19365" target="_blank">05:00 空港送迎</a> 出発</h4>

<h4 id="0535-空港送迎-tpe-桃園国際空港-t2-第二ターミナル到着"><a href="https://www.kkday.com/zh-tw/trans/airport_transfer?cid=19365" target="_blank">05:35 空港送迎</a> TPE 桃園国際空港 T2 第二ターミナル到着</h4>

<p><img src="/assets/055527a739dd/1*6_vxPCIXLx06F53yP4zS3g.webp" alt="" loading="lazy" decoding="async" width="1066" height="512" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDY2IiBoZWlnaHQ9IjUxMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*6_vxPCIXLx06F53yP4zS3g.png" /></p>

<p>端の方に割り当てられ、カウンターは06:10にオープンしました。</p>

<p><img src="/assets/055527a739dd/1*2LMJVQ9PSoJkWNLER6nBfA.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*2LMJVQ9PSoJkWNLER6nBfA.jpeg" /></p>

<p>空き時間に先に<a href="https://www.kkday.com/zh-tw/product/137689-japan-unlimited-data-esim-card?cid=19365" target="_blank">日本のeSIMを有効化</a>。</p>

<h4 id="0640-完了-チェックイン荷物預け入れ出国審査">06:40 完了 チェックイン＋荷物預け入れ＋出国審査</h4>

<p>チェックインと荷物預けは早めに来たためかあまり時間がかかりませんでした。出国審査は混雑していましたが、スムーズに進み、約06:40には出国できました。</p>

<p><img src="/assets/055527a739dd/1*oOO3XXdFpobNN_KqNEtOyw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*oOO3XXdFpobNN_KqNEtOyw.jpeg" /></p>

<p>ゆったりと朝食を楽しむ Zzzzz。</p>

<h4 id="0730-搭乗待ち時間に散策--d6-搭乗口">07:30 搭乗待ち時間に散策 — D6 搭乗口</h4>

<p><img src="/assets/055527a739dd/1*G4-ZNKS-LpmIN5tRNEHe6g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*G4-ZNKS-LpmIN5tRNEHe6g.jpeg" /></p>

<p>搭乗まで少し時間があったので、先に<a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E6%9D%B1%E4%BA%AC%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-%E5%B7%9D%E8%B6%8A%E5%B0%8F%E6%B1%9F%E6%88%B6%E4%B8%80%E6%97%A5%E9%81%8A%E8%88%87%E7%86%B1%E6%B5%B7%E6%B5%B7%E4%B8%8A%E8%8A%B1%E7%81%AB%E5%A4%A7%E6%9C%83%E5%85%A8%E7%B4%80%E9%8C%84-958599363857/#%E4%BA%8C%E8%88%AA%E5%87%BA%E5%A2%83%E5%85%8D%E7%A8%85%E5%BA%97-le-labo" target="_blank">D1で無料マッサージチェアに座る（トークンは近くの店舗で入手可能）</a> 。</p>

<h4 id="0750-搭乗準備">07:50 搭乗準備</h4>

<p><img src="/assets/055527a739dd/1*TqzxK3cXR-j2tfGBVLspow.webp" alt="" loading="lazy" decoding="async" width="2048" height="1536" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDQ4IiBoZWlnaHQ9IjE1MzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*TqzxK3cXR-j2tfGBVLspow.jpeg" /></p>

<h4 id="0838-飛行機離陸-tpe---cts">08:38 飛行機離陸 TPE -&gt; CTS</h4>

<p><img src="/assets/055527a739dd/1*kGuZuIVYW2fYPb3clzIfXg.webp" alt="" loading="lazy" decoding="async" width="788" height="512" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3ODgiIGhlaWdodD0iNTEyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*kGuZuIVYW2fYPb3clzIfXg.png" /></p>

<p>乗ったのはチャイナエアラインの比較的新しい飛行機、Airbus A330–300で、スペースが広く、機内エンターテインメントも充実しています。</p>

<p><img src="/assets/055527a739dd/1*jTKu8WMuRVfU9IZTxQvfpg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*jTKu8WMuRVfU9IZTxQvfpg.jpeg" /></p>

<p>食べ物は…まあまあでした。</p>

<blockquote>
  <p><em>飛行時間は約3時間50分で、軽食も提供されます。</em></p>
</blockquote>

<h4 id="1322-飛行機が到着-tpe---cts">13:22 飛行機が到着 TPE -&gt; CTS</h4>

<p><img src="/assets/055527a739dd/1*TAHPtMwcNQIVPH7AohEhOg.webp" alt="" loading="lazy" decoding="async" width="786" height="512" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3ODYiIGhlaWdodD0iNTEyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*TAHPtMwcNQIVPH7AohEhOg.png" /></p>

<h4 id="1410-入国手続き荷物受取完了">14:10 入国手続き＋荷物受取完了</h4>

<p>入国はかなり早かったですが、荷物の受け取りに長く待ちました。人が多かったのかもしれません（全席完売でした）。</p>

<p><img src="/assets/055527a739dd/1*b35AwJ_fwCxrOJqJGcwOTg.webp" alt="" loading="lazy" decoding="async" width="2112" height="878" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMTEyIiBoZWlnaHQ9Ijg3OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*b35AwJ_fwCxrOJqJGcwOTg.png" /></p>

<p>空港を出たら、「国内線、JR線」の案内表示に従って進みます。</p>

<p><img src="/assets/055527a739dd/1*UFM6K_85XwH7g19kKd6vRA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*UFM6K_85XwH7g19kKd6vRA.jpeg" /></p>

<p>別の建物のロビーに着いたら、地下1階に降りるとJRの駅があります。（エスカレーターの場合は少し回り道が必要です）</p>

<p><img src="/assets/055527a739dd/1*yTccLA73k_OJ6E5OKFMWQw.webp" alt="時刻表" loading="lazy" decoding="async" width="931" height="862" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzEiIGhlaWdodD0iODYyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*yTccLA73k_OJ6E5OKFMWQw.png" /></p>

<p><a href="https://jrhokkaidonorikae.com/vtime/vtime.php?s=9650&amp;d=20260419" target="_blank">時刻表</a></p>

<h4 id="1429-新千歳空港駅から区間快速に乗って札幌駅へ向かう">14:29 新千歳空港駅から区間快速に乗って札幌駅へ向かう</h4>

<p><img src="/assets/055527a739dd/1*J47APGl3TjqzWKm7XQQJrA.webp" alt="&lt;https://www.jrhokkaido.co.jp/global/chinese/travel/airport.html&gt;" loading="lazy" decoding="async" width="1101" height="564" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTAxIiBoZWlnaHQ9IjU2NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*J47APGl3TjqzWKm7XQQJrA.png" /></p>

<p><a href="https://www.jrhokkaido.co.jp/global/chinese/travel/airport.html" target="_blank">https://www.jrhokkaido.co.jp/global/chinese/travel/airport.html</a></p>

<ul>
  <li>
    <p><a href="https://www.jrhokkaido.co.jp/global/chinese/travel/airport.html" target="_blank">札幌 &lt;-&gt; 新千歳空港の所要時間は約33〜41分；<strong>Kitaca、Suica、PASMOなどのICカードが利用可能で、自動券売機に並ぶ必要はありません</strong>。1日あたり163本の運行で非常に頻繁です。</a></p>
  </li>
  <li>
    <p><a href="https://www.jrhokkaido.co.jp/global/chinese/travel/airport.html" target="_blank">5両自由席、1両指定席</a></p>
  </li>
</ul>

<p><img src="/assets/055527a739dd/1*6UaZZp6c43PLTj9EhJT36w.webp" alt="" loading="lazy" decoding="async" width="965" height="781" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjUiIGhlaWdodD0iNzgxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*6UaZZp6c43PLTj9EhJT36w.png" /></p>

<blockquote>
  <p><strong><em>Suicaカードで直接改札を通れますが、</em></strong> <em>お釣りが欲しかったので、あえて切符を買いました。</em></p>
</blockquote>

<h4 id="1506-札幌駅に到着">15:06 札幌駅に到着</h4>

<p><img src="/assets/055527a739dd/1*UgPpbSYwAcb02Kb74ML8lw.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*UgPpbSYwAcb02Kb74ML8lw.jpeg" /></p>

<ul>
  <li>トイレに行って、何か食べ物を買ってから27番のバス停へ向かい続ける</li>
</ul>

<h4 id="1515-札幌駅-27番のりばかっぱライナー乗り場へ向かう">15:15 <a href="https://maps.app.goo.gl/MScVjZQHnW84qn626" target="_blank">札幌駅 27番のりば（かっぱライナー乗り場）</a>へ向かう</h4>

<p><img src="/assets/055527a739dd/1*8ARDa4cvMa0NvmAMXENJkQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="929" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkyOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*8ARDa4cvMa0NvmAMXENJkQ.png" /></p>

<h4 id="1525-到着-札幌駅-27番のりば-kappa-line-乗車場所-待機">15:25 到着 <a href="https://maps.app.goo.gl/MScVjZQHnW84qn626" target="_blank">札幌駅 27番のりば (Kappa Line 乗車場所)</a> 待機</h4>

<p><img src="/assets/055527a739dd/1*XQcnNbnu6N_IBLvKtW_5Fg.webp" alt="" loading="lazy" decoding="async" width="4696" height="2060" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0Njk2IiBoZWlnaHQ9IjIwNjAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*XQcnNbnu6N_IBLvKtW_5Fg.png" /></p>

<blockquote>
  <p><em>札幌駅前の出口を出て左に曲がり、次の交差点を右に曲がると見えます。後ろには赤いビルがあります。</em></p>
</blockquote>

<ul>
  <li>日本のサービスは安心で、ここでもスタッフが定山渓に行くことと予約があるかを確認してくれます。</li>
</ul>

<h4 id="1600-定山渓温泉へ出発">16:00 定山渓温泉へ出発</h4>

<p><img src="/assets/055527a739dd/1*mX62B7-0IYGOOkiCFard2g.webp" alt="" loading="lazy" decoding="async" width="2504" height="2036" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTA0IiBoZWlnaHQ9IjIwMzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*mX62B7-0IYGOOkiCFard2g.png" /></p>

<ul>
  <li>
    <p><a href="https://jotetsu.quicktrip.jp/bought" target="_blank">携帯で予約サイトにログインし、スタッフに画面を見せるだけでそのまま乗車できます。</a></p>
  </li>
  <li>
    <p>観光バスなので、スーツケースは直接スタッフに渡して車内に預ければ問題ありません。</p>
  </li>
</ul>

<p><img src="/assets/055527a739dd/1*zDFW68P2S_0QYBuo7WJN8g.webp" alt="" loading="lazy" decoding="async" width="1200" height="794" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*zDFW68P2S_0QYBuo7WJN8g.png" /></p>

<ul>
  <li>車で約50分、3月中旬の市内はほとんど雪がありませんが、郊外にはまだ少し積雪があります。</li>
</ul>

<h4 id="1650-定山渓温泉到着-2白糸の滝-バス停下車">16:50 定山渓温泉到着 (2)白糸の滝 バス停下車</h4>

<p><img src="/assets/055527a739dd/1*U1I_hwru8pgom6R3qG_9jA.webp" alt="" loading="lazy" decoding="async" width="1200" height="795" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*U1I_hwru8pgom6R3qG_9jA.png" /></p>

<ul>
  <li>
    <p>Kappa Lineのバスの塗装は、定山渓温泉のマスコットキャラクターである河童です。</p>
  </li>
  <li>
    <p><strong>降車時に運転手に電子チケットを見せ、荷物を取ることを伝えてください</strong></p>
  </li>
  <li>
    <p>バスを降りて、前の道路を渡ると、今日宿泊する温泉旅館に到着します！</p>
  </li>
</ul>

<h4 id="1700-到着-jozankei-yurakusoan-ゆらく草庵-和風温泉旅館">17:00 到着 <a href="https://maps.app.goo.gl/mi1LRdo79NghFL3n7" target="_blank">Jozankei Yurakusoan ゆらく草庵 和風温泉旅館</a></h4>

<p><img src="/assets/055527a739dd/1*jXijzCdM080XooCnRKifIQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="797" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*jXijzCdM080XooCnRKifIQ.png" /></p>

<p>非常に伝統的な和風で、ホテル全体が木造建築です。ロビーに入ると畳があり、靴を脱いで靴箱に入れます。</p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/aQBG5TI_Zzg" title="Jozankei Yurakusoan ゆらく草庵 日式溫泉飯店" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<ul>
  <li>房間很大有獨立的廁所、私人衛浴/湯屋、客廳跟床；厲害的是雖然是傳統木造榻榻米但是整體維護的非常好， <strong>沒有任何髒髒舊舊或是霉味的感覺</strong> 。</li>
  <li>也有公共的私人湯屋可以使用 (有好幾間，沒人就可以進去)</li>
</ul>

<h4 id="1800-食事に出かける">18:00 食事に出かける</h4>

<p>ホテルは一泊二食付きですが、私たちは一泊朝食付きで予約しました。外に食べに行きます。</p>

<h4 id="1810-北の国定山渓万世閣ホテルミリオーネ3階">18:10 <a href="https://maps.app.goo.gl/x1Wu1bSFXkk8PDbm7" target="_blank">北の国｜定山渓万世閣・ホテルミリオーネ3階</a></h4>

<p>温泉街はほとんど宿泊＋食事のため、外のレストランはあまりありません；最後に別のホテル <a href="https://maps.app.goo.gl/x1Wu1bSFXkk8PDbm7" target="_blank">万世閣</a> の3階にある居酒屋で夕食を取りました。</p>

<p><img src="/assets/055527a739dd/1*iCfHKvgNp00NMpSeW_MnXw.webp" alt="" loading="lazy" decoding="async" width="1200" height="424" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*iCfHKvgNp00NMpSeW_MnXw.png" /></p>

<ul>
  <li>
    <p>第一杯：正 — 札幌生ビール</p>
  </li>
  <li>
    <p>とんかつ丼と名物のフナの唐揚げを食べました（とても美味しかったです）</p>
  </li>
</ul>

<h4 id="1930-ホテルに戻って温泉で休憩">19:30 ホテルに戻って温泉で休憩</h4>

<p><img src="/assets/055527a739dd/1*IqDyTM7yqweHmbUSLNZSRQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="576" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*IqDyTM7yqweHmbUSLNZSRQ.png" /></p>

<ul>
  <li>幸い、道中にコンビニが多く、帰りにファミリーマートで夜食を買って夜に食べました。</li>
</ul>

<blockquote>
  <p><em>雪は降っていませんが、夜になるとまだとても寒いです。一日中移動して疲れたので、早めにホテルに戻って温泉に入り休みました。</em></p>
</blockquote>

<h3 id="day-2-0316-月--定山渓温泉街札幌市内観光スポット">Day 2 (03/16 月) — 定山渓温泉街、札幌市内観光スポット</h3>

<h4 id="0900-朝食を食べる">09:00 朝食を食べる</h4>

<p><img src="/assets/055527a739dd/1*ypWZE7fthJG5vBU8uC_F2A.webp" alt="" loading="lazy" decoding="async" width="1200" height="452" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQ1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*ypWZE7fthJG5vBU8uC_F2A.png" /></p>

<p>ちょうど窓側の席が割り当てられ、窓の外の景色がとても美しかったです。</p>

<p><img src="/assets/055527a739dd/1*zIdJFU-HuUUqDTW20dTX2Q.webp" alt="" loading="lazy" decoding="async" width="1200" height="574" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU3NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*zIdJFU-HuUUqDTW20dTX2Q.png" /></p>

<blockquote>
  <p><em>朝食はとても豪華でした：主にご飯／野菜ご飯、味噌汁、(1) 蒸し豚肉と野菜、(2) 冷たい鮭 — 中央のアルミホイルを酒燈で温められます、(3) 玉子焼き。</em></p>
</blockquote>

<h4 id="1100-チェックアウト後荷物を預けて定山渓温泉街周辺を散策">11:00 チェックアウト後、荷物を預けて定山渓温泉街周辺を散策</h4>

<p><img src="/assets/055527a739dd/1*RIvrEU6Nizz0EnOj-extDw.webp" alt="" loading="lazy" decoding="async" width="1456" height="1151" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDU2IiBoZWlnaHQ9IjExNTEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*RIvrEU6Nizz0EnOj-extDw.png" /></p>

<blockquote>
  <p><em>帰りのバス13:31の乗車まで時間があったので、定山渓温泉を一周散策しました。</em></p>
</blockquote>

<h4 id="1110-定山渓神社">11:10 定山渓神社</h4>

<p><img src="/assets/055527a739dd/1*otr7MA3QH-m__iTJI6AxWg.webp" alt="" loading="lazy" decoding="async" width="960" height="1280" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjAiIGhlaWdodD0iMTI4MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*otr7MA3QH-m__iTJI6AxWg.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*gOkeBho1WpoY-Bowj3e5qA.webp" alt="" loading="lazy" decoding="async" width="902" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*gOkeBho1WpoY-Bowj3e5qA.png" /></p>

<p>神社全体が大雪で凍りついていました。</p>

<h4 id="1130-河童家族の祈願手湯"><a href="https://maps.app.goo.gl/q9rNER1WAPXw9DPH7" target="_blank">11:30 河童家族の祈願手湯</a></h4>

<p><img src="/assets/055527a739dd/1*dBB1541WoB5lOVGSfaG44g.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*dBB1541WoB5lOVGSfaG44g.jpeg" /></p>

<p>簡単に手を洗う。</p>

<p>隣の斜面を下ると温泉公園です。</p>

<h4 id="1140-定山源泉公園"><a href="https://maps.app.goo.gl/j7K1pCCkWTsPX2uKA" target="_blank">11:40 定山源泉公園</a></h4>

<p><img src="/assets/055527a739dd/1*e4RVh1Mg-cxup8svIuUpPw.webp" alt="" loading="lazy" decoding="async" width="1200" height="792" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*e4RVh1Mg-cxup8svIuUpPw.png" /></p>

<p>公園には公共の足湯と、ゆで卵を作れる湧き口があります。</p>

<p><img src="/assets/055527a739dd/1*FVNqZAQ-8GVQsEcLza7uMg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*FVNqZAQ-8GVQsEcLza7uMg.jpeg" /></p>

<blockquote>
  <p><em>温泉卵を作りたい場合は、橋を渡って向かいの<a href="https://maps.app.goo.gl/JQ8MedX36trBSw7EA" target="_blank">㈱定山渓物産館 中央店</a>で温泉卵を購入し、そこで茹でてから店内で食べることができます。</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*JXKfDrv0HzbuwK7HENsOcA.webp" alt="" loading="lazy" decoding="async" width="3004" height="1996" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDA0IiBoZWlnaHQ9IjE5OTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*JXKfDrv0HzbuwK7HENsOcA.png" /></p>

<h4 id="1200-ふる川果日-jglacée-を通過"><a href="https://maps.app.goo.gl/iUFZh6uSjqmqffw88" target="_blank">12:00 ふる川果日 J.glacée を通過</a></h4>

<p><img src="/assets/055527a739dd/1*Ap1oNMTiOhNzn6JBFs6mcg.webp" alt="" loading="lazy" decoding="async" width="1200" height="798" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*Ap1oNMTiOhNzn6JBFs6mcg.png" /></p>

<p>さらに上に歩いていくとパン屋さんがあり、焼きたてのアップルクロワッサンがあったので、ひとつ買ってみました。味はなかなか良かったです。</p>

<h4 id="1215-岩戸観音堂を通過"><a href="https://maps.app.goo.gl/6Ymw95Ptk4BNpX1z6" target="_blank">12:15 岩戸観音堂を通過</a></h4>

<p><img src="/assets/055527a739dd/1*QxUH_qMGIGBPCNJNG16zBw.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*QxUH_qMGIGBPCNJNG16zBw.jpeg" /></p>

<p>ここを通り過ぎて前に進み、さらに下に行くと出発点のホテルに戻ります。</p>

<p><img src="/assets/055527a739dd/1*BhscZ015lnl7cK7NxMlAPA.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*BhscZ015lnl7cK7NxMlAPA.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*qYBqoqgOiP2n19HP1pwXEg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*qYBqoqgOiP2n19HP1pwXEg.jpeg" /></p>

<p>以前の雪の多さが想像できますね。川の上の吊り橋も雪と氷で覆われていました！</p>

<h4 id="1230-ホテルに戻る">12:30 ホテルに戻る</h4>

<p>まだ時間があったので、近くの白糸の滝を見に行きました。</p>

<p><img src="/assets/055527a739dd/1*wOsNH9LlgSPzBv2LHxB3aA.webp" alt="" loading="lazy" decoding="async" width="3312" height="2210" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMzEyIiBoZWlnaHQ9IjIyMTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*wOsNH9LlgSPzBv2LHxB3aA.png" /></p>

<p>坂を曲がって下る予定でしたが、残念ながら雪と氷で封鎖されており、開放されていませんでした。</p>

<h4 id="1310-ホテルに戻って荷物を取る">13:10 ホテルに戻って荷物を取る</h4>

<h4 id="1315-到着-2-白糸の滝-バス停来た時の反対側">13:15 到着 <a href="https://maps.app.goo.gl/XE4wcHVAofeew1DQ8" target="_blank">(2) 白糸の滝 バス停（来た時の反対側）</a></h4>

<p><img src="/assets/055527a739dd/1*6fAEfLztaLDeyirDO8CTmg.webp" alt="" loading="lazy" decoding="async" width="2956" height="1964" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOTU2IiBoZWlnaHQ9IjE5NjQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*6fAEfLztaLDeyirDO8CTmg.png" /></p>

<p><img src="/assets/055527a739dd/1*m8v0h-nb67YzZWgkldbdBQ.webp" alt="" loading="lazy" decoding="async" width="960" height="1280" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjAiIGhlaWdodD0iMTI4MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*m8v0h-nb67YzZWgkldbdBQ.jpeg" /></p>

<p>私たちのバスは13:15に始発駅を出発し、13:31に白糸の滝駅に到着予定です。待ち時間が退屈なので、雪の上を歩いてみました。</p>

<h4 id="1340-札幌駅へ戻るために乗車">13:40 札幌駅へ戻るために乗車</h4>

<ul>
  <li>乗車時と降車時に同じ電子チケットを運転手に提示してください。</li>
</ul>

<h4 id="1450-札幌に戻りkeio-prelia-hotel-sapporo--京王プレリアホテル札幌--札幌京王プレリアホテルにチェックイン">14:50 札幌に戻り、<a href="https://maps.app.goo.gl/JP8qZhQiLpvaFaVq9" target="_blank">Keio Prelia Hotel Sapporo : 京王プレリアホテル札幌 : 札幌京王プレリアホテル</a>にチェックイン</h4>

<p><img src="/assets/055527a739dd/1*ShHQszkicgDZYCPb-3VaHw.webp" alt="" loading="lazy" decoding="async" width="2912" height="1936" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOTEyIiBoZWlnaHQ9IjE5MzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*ShHQszkicgDZYCPb-3VaHw.png" /></p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/6ENDDDNTK8g" title="Keio Prelia Hotel Sapporo : 京王プレリアホテル札幌 : 札幌京王普雷利亞飯店" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<ul>
  <li>飯店很新、設備齊全，房間算大。</li>
  <li>地點在後站比較不熱鬧，要走一小段、札幌站也沒藥妝店； <strong>相較之下大通站周邊比較熱鬧。</strong></li>
</ul>

<blockquote>
  <p><em>15:20頃に身支度を整えて再出発。昼食は取らず、早めに大通公園付近で夕食を取る予定。</em></p>
</blockquote>

<h4 id="1530-ヨドバシ">15:30 <a href="https://maps.app.goo.gl/AGEuLosKQh1iSNE4A" target="_blank">ヨドバシ</a></h4>

<p><img src="/assets/055527a739dd/1*6RC-qsV-DaGBnN-Yd4OSnw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*6RC-qsV-DaGBnN-Yd4OSnw.jpeg" /></p>

<p>ホテルからJR/地下鉄駅へ歩く途中にヨドバシがあり、その後ろに<a href="https://maps.app.goo.gl/3xn9SZskRd8Yzr2t9" target="_blank">マクドナルド</a>があります。ガチャガチャを見に行きました。</p>

<h4 id="1610-薄野すすきの駅に到着">16:10 薄野すすきの駅に到着</h4>

<p><img src="/assets/055527a739dd/1*jdoeeUN6g1laKeVunxxbaQ.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*jdoeeUN6g1laKeVunxxbaQ.jpeg" /></p>

<p>薄野駅まで電車で移動し、札幌で有名な「ジンギスカン」焼肉を食べに行きます。</p>

<h4 id="1615-ジンギスカン-達磨-本店-食事開始">16:15 <a href="https://maps.app.goo.gl/3TvfU2SAzF8beSFm6" target="_blank">ジンギスカン 達磨 本店</a> 食事開始</h4>

<p><img src="/assets/055527a739dd/1*VKpLNNn6ryHdjU0c80J2Cw.webp" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*VKpLNNn6ryHdjU0c80J2Cw.png" /></p>

<ul>
  <li>
    <p>看板メニューの2品と普通の肉1品、白ご飯、生ビール（大ジョッキ…少し大きすぎ）を注文しました。</p>
  </li>
  <li>
    <p>お肉はとても美味しく、羊特有の臭みは全くなく、肉質も柔らかいです。</p>
  </li>
  <li>
    <p>これだけたくさん食べて、一人約700台湾ドルです。</p>
  </li>
</ul>

<blockquote>
  <p><em>店内はあまり広くなく、近くに支店もあります。満腹になって17時近くになると、外にはすでに多くの人が並んでいました。</em></p>
</blockquote>

<h4 id="1700-薄野駅交差点"><a href="https://maps.app.goo.gl/kN9qw85rbk16KAWh6" target="_blank">17:00 薄野駅交差点</a></h4>

<p><img src="/assets/055527a739dd/1*0_Uo2gxSY01IJ7PS2jgWCg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*0_Uo2gxSY01IJ7PS2jgWCg.jpeg" /></p>

<p>お腹がいっぱいになったら、ゆっくり大通駅へ戻ります。札幌で最も有名な交差点を通り過ぎて、<a href="https://maps.app.goo.gl/HdrBr15BZhTY9xoy5" target="_blank">札幌テレビ塔</a>へ行きます。</p>

<h4 id="1715-狸小路を通りながらガチャガチャやドンキホーテを散策">17:15 <a href="https://maps.app.goo.gl/t9UREfvkAkyNrCim6" target="_blank">狸小路を通りながらガチャガチャやドン・キホーテを散策</a></h4>

<p><img src="/assets/055527a739dd/1*Z0HU0h6iFvmVKFFxlFcrTA.webp" alt="" loading="lazy" decoding="async" width="2048" height="911" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDQ4IiBoZWlnaHQ9IjkxMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*Z0HU0h6iFvmVKFFxlFcrTA.png" /></p>

<p>ここにMEGA全館の<a href="https://maps.app.goo.gl/t9UREfvkAkyNrCim6" target="_blank">ドン・キホーテ</a>があります。</p>

<h4 id="1741-札幌テレビ塔">17:41 <a href="https://maps.app.goo.gl/HdrBr15BZhTY9xoy5" target="_blank">札幌テレビ塔</a></h4>

<p><img src="/assets/055527a739dd/1*uW87zB98sSmv7KTGQBwWRw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*uW87zB98sSmv7KTGQBwWRw.jpeg" /></p>

<h4 id="1830-札幌テレビ塔-夜景">18:30 <a href="https://maps.app.goo.gl/HdrBr15BZhTY9xoy5" target="_blank">札幌テレビ塔</a> 夜景</h4>

<p><img src="/assets/055527a739dd/1*66Xgue8l-kfCCv_N8iGa3Q.webp" alt="" loading="lazy" decoding="async" width="1200" height="798" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*66Xgue8l-kfCCv_N8iGa3Q.png" /></p>

<p>札幌タワーには約18:30まで滞在し、夜景を見た後に降りました。</p>

<p><img src="/assets/055527a739dd/1*XgVlX-8dfSDPQzb3ajJzug.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*XgVlX-8dfSDPQzb3ajJzug.jpeg" /></p>

<p>ついでにスタンプを押して、ポストカードを集めることもできます。</p>

<p><img src="/assets/055527a739dd/1*D5X9adov6oTZWgf4qOMZUQ.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*D5X9adov6oTZWgf4qOMZUQ.jpeg" /></p>

<h4 id="1840-parco-札幌-ショッピング"><a href="https://maps.app.goo.gl/pexoh92RLGVdG9N36" target="_blank">18:40 PARCO 札幌</a> ショッピング</h4>

<p><img src="/assets/055527a739dd/1*f44BK8MmMCPBRjyRgD9N4g.webp" alt="" loading="lazy" decoding="async" width="3540" height="1560" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTQwIiBoZWlnaHQ9IjE1NjAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*f44BK8MmMCPBRjyRgD9N4g.png" /></p>

<p>テレビ塔を出て次の交差点がParco札幌店です。ちょっと買い物に寄りましょう。</p>

<h4 id="2030-コンビニで夜食を買ってホテルで休憩">20:30 コンビニで夜食を買ってホテルで休憩</h4>

<p><img src="/assets/055527a739dd/1*x52OxjlfB-Udv1DWwxrSVA.webp" alt="" loading="lazy" decoding="async" width="1200" height="449" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQ0OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*x52OxjlfB-Udv1DWwxrSVA.png" /></p>

<p>夕食は早めに食べたので、夜食を多めに食べることにしました；コンビニでカップラーメン＋串焼き＋唐揚げ、そしてイチゴのフルーツ酒（美味しい）と<a href="https://the-sapporo-bar.susukino-brewing.com/" target="_blank"><strong>北海道 The Sapporo Bar 物語コラボのウイスキーチョコレートアイスクリーム</strong></a>を買いました（本当にお酒の味がして、なかなか美味しいです）。</p>

<h3 id="day-3-0317-火--小樽小樽水族館">Day 3 (03/17 火) — 小樽、小樽水族館</h3>

<h4 id="0930-出発">09:30 出発</h4>

<p><img src="/assets/055527a739dd/1*NCc4ExDsn14kx-uIpTxBWw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*NCc4ExDsn14kx-uIpTxBWw.jpeg" /></p>

<p>車内でマクドナルドの朝食を買って食べる。</p>

<h4 id="1000-札幌駅で乗車し小樽駅へ向かう">10:00 札幌駅で乗車し小樽駅へ向かう</h4>

<p><img src="/assets/055527a739dd/1*sVzzX65_gTfTTnwA5kG-XA.webp" alt="" loading="lazy" decoding="async" width="379" height="153" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNzkiIGhlaWdodD0iMTUzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*sVzzX65_gTfTTnwA5kG-XA.png" /></p>

<blockquote>
  <p><strong><em>結果は普通列車で、とても混んでいて立ちっぱなしでした。</em></strong> <em>車内で食事をする余裕は全くありませんでした。</em></p>
</blockquote>

<h4 id="1042-小樽駅に到着">10:42 小樽駅に到着</h4>

<p><img src="/assets/055527a739dd/1*pH7YPEhWohZ5L9mVmdhX7A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*pH7YPEhWohZ5L9mVmdhX7A.jpeg" /></p>

<p>この人混みを見れば、多くの人が小樽に来ているのがわかります。</p>

<h4 id="1045-小樽駅">10:45 小樽駅</h4>

<p><img src="/assets/055527a739dd/1*0oQhRkSceYFsf3jHZwV9Bg.webp" alt="" loading="lazy" decoding="async" width="1074" height="810" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDc0IiBoZWlnaHQ9IjgxMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*0oQhRkSceYFsf3jHZwV9Bg.png" /></p>

<p>小樽駅正面を出て、横断歩道を渡った右側にバス停があります。直接3番乗り場で <strong>10 小樽水族館線</strong> を待ちます：</p>

<p><img src="/assets/055527a739dd/1*1iMFSEhrHNtnxkYzh8O30Q.webp" alt="画像出典：Google Map - K T (torute)" loading="lazy" decoding="async" width="935" height="907" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzUiIGhlaWdodD0iOTA3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*1iMFSEhrHNtnxkYzh8O30Q.png" /></p>

<p><a href="https://maps.app.goo.gl/p7mnP8KpppyUdtwu7" target="_blank">画像出典：Google Map</a> - <a href="https://maps.google.com/maps/contrib/117333353874320617109" target="_blank">K T (torute)</a></p>

<p><img src="/assets/055527a739dd/1*irY-RRWlc8mKIiM6s6bdXw.webp" alt="" loading="lazy" decoding="async" width="734" height="826" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MzQiIGhlaWdodD0iODI2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*irY-RRWlc8mKIiM6s6bdXw.png" /></p>

<ul>
  <li>
    <p><strong>１０小樽水族館線</strong> ：ほぼ直通で、約20分で小樽水族館に到着します。</p>
  </li>
  <li>
    <p><strong>１１祝津線</strong> ：直通ではなく、約30分かかります。</p>
  </li>
</ul>

<h4 id="1110-小樽水族館に到着">11:10 小樽水族館に到着</h4>

<p><img src="/assets/055527a739dd/1*f3ZL6ho5OMt3wYHfVRT-TQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="452" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQ1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*f3ZL6ho5OMt3wYHfVRT-TQ.png" /></p>

<p>カウンターでオンライン購入した<a href="https://www.kkday.com/zh-tw/product/139823-otaru-aquarium-admission-ticket-hokkaido?cid=19365" target="_blank">【公式販売】北海道小樽水族館チケット（購入後すぐ利用可／購入から30日以内有効）</a>のQRコードを提示するだけで、直接入場できます。</p>

<h4 id="小樽水族館自作マップ">小樽水族館自作マップ</h4>

<p><img src="/assets/055527a739dd/1*H0BTCoeqStQ7n4POyH6ymw.webp" alt="" loading="lazy" decoding="async" width="2522" height="1918" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTIyIiBoZWlnaHQ9IjE5MTgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*H0BTCoeqStQ7n4POyH6ymw.png" /></p>

<ul>
  <li>
    <p>冬季は観覧車が閉鎖されており、観覧車は水族館の敷地内にないため、別途チケットが必要です。</p>
  </li>
  <li>
    <p>小樽水族館は規模は大きくないですが、種類が豊富で飼育も丁寧です。ショーも多く、全体的な体験は良好です。</p>
  </li>
  <li>
    <p>赤色はペンギンの散歩ルートです</p>
  </li>
</ul>

<p><img src="/assets/055527a739dd/1*VpRX9psi2InntONIV365jA.webp" alt="時間は季節によって異なりますので、公式サイトの情報 をご参照ください。" loading="lazy" decoding="async" width="3116" height="1400" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMTE2IiBoZWlnaHQ9IjE0MDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*VpRX9psi2InntONIV365jA.png" /></p>

<p>時間は季節によって異なりますので、<a href="https://uu-beihaidao.tw/corporate/otaru-aq.shtml" target="_blank">公式サイトの情報</a> をご参照ください。</p>

<h4 id="入場後右に曲がり下へ進む--海獣公園">入場後右に曲がり、下へ進む — 海獣公園</h4>

<p><img src="/assets/055527a739dd/1*HjDF6BvQMKbWcx1HpFS4yA.webp" alt="" loading="lazy" decoding="async" width="1200" height="913" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkxMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*HjDF6BvQMKbWcx1HpFS4yA.png" /></p>

<p><img src="/assets/055527a739dd/1*frqiW_5h5tX81n9DqKUXlw.webp" alt="" loading="lazy" decoding="async" width="1200" height="685" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY4NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*frqiW_5h5tX81n9DqKUXlw.png" /></p>

<p>ここは上り坂にだけエスカレーターがあり、下り坂はかなり揺れます。</p>

<p><strong>すべての屋外パフォーマンスはここで行われます：</strong></p>

<ul>
  <li>
    <p>アザラシのショー：到着時の11:20に公演中でした</p>
  </li>
  <li>
    <p>北海アシカのショー（超大型アシカ）：11:40</p>
  </li>
  <li>
    <p>ペンギンピクニック：12:00</p>
  </li>
  <li>
    <p>ペンギンの活動：見られませんでした</p>
  </li>
  <li>
    <p>セイウチの餌探し解説：見られませんでした</p>
  </li>
</ul>

<p><img src="/assets/055527a739dd/1*DB-wHVOUcIjP73sMVSXeCA.webp" alt="" loading="lazy" decoding="async" width="2804" height="2350" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyODA0IiBoZWlnaHQ9IjIzNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*DB-wHVOUcIjP73sMVSXeCA.png" /></p>

<h4 id="1140-ホッキョクグマのショー">11:40 ホッキョクグマのショー</h4>

<p><img src="/assets/055527a739dd/1*0cK0DaJLgqU8v2aqloSntg.webp" alt="" loading="lazy" decoding="async" width="3966" height="1756" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzOTY2IiBoZWlnaHQ9IjE3NTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*0cK0DaJLgqU8v2aqloSntg.png" /></p>

<p>到着時間が早くて、最前列に立てました。ホッキョクグマは本当に大きいです！</p>

<h4 id="アザラシ">アザラシ</h4>

<p><img src="/assets/055527a739dd/1*VlGMYBS8lHbzv--Fnoccxg.webp" alt="" loading="lazy" decoding="async" width="4086" height="1964" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MDg2IiBoZWlnaHQ9IjE5NjQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*VlGMYBS8lHbzv--Fnoccxg.png" /></p>

<p>ショーを見終わった隣にはアザラシのプールがあり、どのアザラシもとてもリラックスしていました。</p>

<blockquote>
  <p><em>アザラシやオットセイには魚を購入して餌やり体験ができます。<strong>数量限定で、餌やり禁止のプールもあるため、表示をよく確認してください。</strong></em></p>
</blockquote>

<h4 id="1200-ペンギン散歩">12:00 ペンギン散歩</h4>

<p><img src="/assets/055527a739dd/1*OI0aGYtaim4YBadFYp91nQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="602" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjYwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*OI0aGYtaim4YBadFYp91nQ.png" /></p>

<blockquote>
  <p><em>ルートは上の図の赤い線の通りで、最後にペンギン池で水浴びします。</em></p>
</blockquote>

<p>アザラシを見た後はペンギンのお散歩ルートへ。床に白い線があり、その線の外側に立ってペンギンが通るのを待ちます。私は角のこの場所に立っていました（上の写真の人の位置）。</p>

<p><img src="/assets/055527a739dd/1*FxieyG5_jW2rSbBjlz4jPg.webp" alt="" loading="lazy" decoding="async" width="1928" height="1772" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOTI4IiBoZWlnaHQ9IjE3NzIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*FxieyG5_jW2rSbBjlz4jPg.png" /></p>

<p>小さなペンギンで、南崁のペンギンに少し似ています。</p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/iGPgTEcVJWc" title="小樽水族館 企鵝散步 (海獸公園) / おたる水族館 ペンギンの海まで遠足（海獣公園） / Otaru Aquarium Penguin Picnic (Marine mammal park)" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p><strong>最終的にはペンギンプールの泡の水にたどり着く：</strong></p>

<p><img src="/assets/055527a739dd/1*AC942rnUoH5eUTxG8hpdfQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*AC942rnUoH5eUTxG8hpdfQ.jpeg" /></p>

<h4 id="室内にいる他の動物たちも見に行きましたアザラシセイウチ">室内にいる他の動物たちも見に行きました：（アザラシ、セイウチ）</h4>

<p><img src="/assets/055527a739dd/1*L4Ow3BnB1I2VaSfm-HraCw.webp" alt="" loading="lazy" decoding="async" width="1200" height="794" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*L4Ow3BnB1I2VaSfm-HraCw.png" /></p>

<p>見学後、イルカ館の方向へ移動：</p>

<p><img src="/assets/055527a739dd/1*YJq8kpXFK_b7gwOu7fw9tQ.webp" alt="" loading="lazy" decoding="async" width="2808" height="1638" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyODA4IiBoZWlnaHQ9IjE2MzgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*YJq8kpXFK_b7gwOu7fw9tQ.png" /></p>

<p>イルカ館の外にも小さなペンギン池があります：</p>

<p><img src="/assets/055527a739dd/1*eSjHmjQ2Xb6J1mQjH93i1Q.webp" alt="" loading="lazy" decoding="async" width="2048" height="1536" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDQ4IiBoZWlnaHQ9IjE1MzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*eSjHmjQ2Xb6J1mQjH93i1Q.jpeg" /></p>

<h4 id="1240-南海ライオンイルカショー">12:40 南海ライオン＋イルカショー</h4>

<p><img src="/assets/055527a739dd/1*zApgCBreekd_oHyGNhuGmA.webp" alt="" loading="lazy" decoding="async" width="1200" height="798" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*zApgCBreekd_oHyGNhuGmA.png" /></p>

<p>見学を終えて本館に戻り、市内の海洋生物を見学：</p>

<p><img src="/assets/055527a739dd/1*7JOgPNrhoEEWZ9fvaDk7dw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*7JOgPNrhoEEWZ9fvaDk7dw.jpeg" /></p>

<p>種類もかなり豊富です。</p>

<p><strong>日本最高齢のコツメカワウソ：</strong></p>

<p><img src="/assets/055527a739dd/1*2TlrnSrYe31PT_qlk9RrMQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="577" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU3NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*2TlrnSrYe31PT_qlk9RrMQ.png" /></p>

<blockquote>
  <p><em>このカワウソは年を取っていて、動きがよろよろと遅いので、みんなはもう彼の晩年を邪魔しないであげてください。</em></p>
</blockquote>

<p>お土産店を見終わった後、来たバス停に戻ってバスを待ちました。</p>

<h4 id="1400-バスで小樽駅へ戻る">14:00 バスで小樽駅へ戻る</h4>

<h4 id="1420-小樽駅に戻る">14:20 小樽駅に戻る</h4>

<p>駅前通りを歩いて小樽運河の方向へ向かいます。</p>

<p><img src="/assets/055527a739dd/1*eCDjh5Dp6zq7Lra8dZyQzg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*eCDjh5Dp6zq7Lra8dZyQzg.jpeg" /></p>

<p>通りの突き当たり近くにLeTAO運河店が見えます：</p>

<p><img src="/assets/055527a739dd/1*j9S4vpv8COBT_jiAu_95wA.webp" alt="" loading="lazy" decoding="async" width="3360" height="1916" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMzYwIiBoZWlnaHQ9IjE5MTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*j9S4vpv8COBT_jiAu_95wA.png" /></p>

<p><img src="/assets/055527a739dd/1*sPnweRj4fwtR97NXNLchTw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*sPnweRj4fwtR97NXNLchTw.jpeg" /></p>

<p>こちらではお土産のほかに、アイスクリームやスイーツ、惣菜やカフェも販売している<a href="https://maps.app.goo.gl/K9PY2rFURawPitX38" target="_blank">ルタオ小樽運河店 三番庫カフェ</a>。</p>

<p><img src="/assets/055527a739dd/1*u-odR1T48phugsDA844MHQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="902" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*u-odR1T48phugsDA844MHQ.png" /></p>

<blockquote>
  <p><em>クッキーはとても美味しかったですが、もう一つの缶入りのいちごチョコレートは少し甘すぎました。</em></p>
</blockquote>

<h4 id="1440-ルタオ小樽運河店-三番庫カフェ-昼食を食べる"><a href="https://maps.app.goo.gl/K9PY2rFURawPitX38" target="_blank">14:40 ルタオ小樽運河店 三番庫カフェ</a> 昼食を食べる</h4>

<p><img src="/assets/055527a739dd/1*Pm2hpXp23qw2J1hKJ0oixg.webp" alt="" loading="lazy" decoding="async" width="3998" height="1502" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzOTk4IiBoZWlnaHQ9IjE1MDIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*Pm2hpXp23qw2J1hKJ0oixg.png" /></p>

<p>適当にパスタの惣菜を選んでお腹を満たし、デザートセット（ケーキが美味しかった）もいただきました。</p>

<h4 id="1600-小樽運河散策">16:00 小樽運河散策</h4>

<p><img src="/assets/055527a739dd/1*64MslNJEByUEGfoSK0YTGA.webp" alt="" loading="lazy" decoding="async" width="2048" height="1536" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDQ4IiBoZWlnaHQ9IjE1MzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*64MslNJEByUEGfoSK0YTGA.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*6XxJGWGJCVSZGo-sualLdg.webp" alt="" loading="lazy" decoding="async" width="612" height="711" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MTIiIGhlaWdodD0iNzExIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*6XxJGWGJCVSZGo-sualLdg.png" /></p>

<p>お腹がいっぱいになったら、小樽運河を散歩しながら、<a href="https://maps.app.goo.gl/fX5yyT2tVRV8Lo98A" target="_blank">小樽蒸気時計</a> へ向かいます。</p>

<p><img src="/assets/055527a739dd/1*xCKpu7uLjK8VgfkbRuCSAQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*xCKpu7uLjK8VgfkbRuCSAQ.jpeg" /></p>

<p><a href="https://maps.app.goo.gl/fX5yyT2tVRV8Lo98A" target="_blank">小樽蒸気時計</a> の周辺には、多くの小さな店やお土産屋、琉璃製品店が立ち並んでいます。</p>

<p><img src="/assets/055527a739dd/1*kzVBtUi0gLMICty86NrsSA.webp" alt="" loading="lazy" decoding="async" width="3988" height="1746" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzOTg4IiBoZWlnaHQ9IjE3NDYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*kzVBtUi0gLMICty86NrsSA.png" /></p>

<p>ここでたくさんのクッキーのお土産を買いました。特に北海道でしか買えない六花亭です。</p>

<p><img src="/assets/055527a739dd/1*skVsoy14UQ1TzJ26bBOShA.webp" alt="" loading="lazy" decoding="async" width="2920" height="1400" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOTIwIiBoZWlnaHQ9IjE0MDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*skVsoy14UQ1TzJ26bBOShA.png" /></p>

<blockquote>
  <p><em>六花亭で必ず買うべきもの — ラム酒クッキー（賞味期限が短く、冷やすとさらに美味しい）、酒入りチョコレート（本物のお酒使用）</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*6TcrcwJUKKGXrSHL1_vJSg.webp" alt="" loading="lazy" decoding="async" width="2724" height="1818" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNzI0IiBoZWlnaHQ9IjE4MTgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*6TcrcwJUKKGXrSHL1_vJSg.png" /></p>

<p>道中にある <a href="https://maps.app.goo.gl/eq7F2zZ5P6RuUJ1H6" target="_blank">北一硝子 Outlet</a> では、北海道の地酒を販売しており、無料で試飲もできます。</p>

<p><img src="/assets/055527a739dd/1*9KidHCaTaB9XSzch8ul8vA.webp" alt="" loading="lazy" decoding="async" width="4123" height="3100" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MTIzIiBoZWlnaHQ9IjMxMDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*9KidHCaTaB9XSzch8ul8vA.png" /></p>

<blockquote>
  <p><em>メロン酒を一本買って帰りました。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>メロンの果肉の濃厚な食感があり、メロンの味も強いので、氷と炭酸水を加えて飲むとさらに美味しくなります。</em></strong></p>
</blockquote>

<h4 id="1710-道の突き当たりまで歩く-小樽蒸気時計">17:10 道の突き当たりまで歩く <a href="https://maps.app.goo.gl/fX5yyT2tVRV8Lo98A" target="_blank">小樽蒸気時計</a></h4>

<p><img src="/assets/055527a739dd/1*F2amQ8v_lM3yYvDnzXta3A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*F2amQ8v_lM3yYvDnzXta3A.jpeg" /></p>

<p>時間は夕方に近づいてきたので、帰り始める。</p>

<p><img src="/assets/055527a739dd/1*4FRDy264prK1bVwCm2BpRw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*4FRDy264prK1bVwCm2BpRw.jpeg" /></p>

<h4 id="1810-小樽駅に戻る">18:10 小樽駅に戻る</h4>

<p><img src="/assets/055527a739dd/1*WI719YuzTLNf4fTMVWBOOg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*WI719YuzTLNf4fTMVWBOOg.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*hcCX6rn7zFpfD38KbgP-Jw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*hcCX6rn7zFpfD38KbgP-Jw.jpeg" /></p>

<p>18:00の快速空港行きに乗れなかったため、適当に遅い便に乗って札幌に戻りました。</p>

<h4 id="1900-札幌駅に戻る">19:00 札幌駅に戻る</h4>

<h4 id="1930-savoy-sapporo-station-kitaguchi-北海道スープカレー">19:30 <a href="https://maps.app.goo.gl/1tAe4EyEFP2r5wC98" target="_blank">Savoy Sapporo Station Kitaguchi</a> 北海道スープカレー</h4>

<p><img src="/assets/055527a739dd/1*uWJwZJH4ZnZq92cIDGUabg.webp" alt="" loading="lazy" decoding="async" width="2612" height="1482" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNjEyIiBoZWlnaHQ9IjE0ODIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*uWJwZJH4ZnZq92cIDGUabg.png" /></p>

<p>ホテルの近くに評価が高く、テイクアウトもできるスープカレー店があり、疲れていたのでホテルに持ち帰って食べました。</p>

<blockquote>
  <p><em>食材はすべて新鮮で、カレーの味が食材の風味を損なわず、さっぱりとして美味しいです。</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*8MK6Ra5FKK9jKxpKwWrIvg.webp" alt="" loading="lazy" decoding="async" width="2356" height="1118" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMzU2IiBoZWlnaHQ9IjExMTgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*8MK6Ra5FKK9jKxpKwWrIvg.png" /></p>

<p>夜食はコンビニのホットドッグ＋メロン酒（これもなかなか良い）＋ヤクルト1000減糖版で乳酸菌を補給（実は毎日飲んでいますが、写真を撮るのが面倒でした）。</p>

<h3 id="day-4-0318-水--kkday-北海道イルミネーションツアー-富良野エルフ台美瑛青い池白髭の滝日帰りツアー札幌発">Day 4 (03/18 水) — <a href="https://www.kkday.com/zh-tw/product/157133-hokkaido-sapporo-biei-blue-pond-illumination-tour-japan?cid=19365" target="_blank"><strong>KKday 北海道イルミネーションツアー ｜富良野エルフ台＆美瑛青い池＆白髭の滝日帰りツアー｜札幌発</strong></a></h3>

<blockquote>
  <p><em>私たちは <strong>ゆったり11:50出発 Bプラン</strong> を選びましたが、夜遅くに到着するため、札幌大通駅には21:40頃に戻る予定です。</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*r4yUA95KAdrxtt6SBKWZfA.webp" alt="" loading="lazy" decoding="async" width="872" height="783" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzIiIGhlaWdodD0iNzgzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*r4yUA95KAdrxtt6SBKWZfA.png" /></p>

<p>集合場所：<a href="https://maps.app.goo.gl/dgPQLs75bVNTbVPR9" target="_blank">大通駅地下鉄31番出口</a>、前日に出発前の案内メールでガイドやドライバーの連絡先が届きます。</p>

<ul>
  <li>
    <p><strong>11:50 発車時間です。必ず11:40までに到着してください</strong></p>
  </li>
  <li>
    <p><strong>11:50 発車時間です。必ず11:40までに到着してください</strong></p>
  </li>
  <li>
    <p><strong>11:50 発車時間です。必ず11:40までに到着してください</strong></p>
  </li>
</ul>

<h4 id="1000-大通駅へ出発">10:00 大通駅へ出発</h4>

<h4 id="1030-近くの-客美多珈琲-大通西二丁目店-で朝食を食べる">10:30 近くの <a href="https://maps.app.goo.gl/3m7TRSjJWUJAWDfi9" target="_blank">客美多珈琲 大通西二丁目店</a> で朝食を食べる</h4>

<p><img src="/assets/055527a739dd/1*HpkfNpNAwG8fjJ-Cm9BsUg.webp" alt="" loading="lazy" decoding="async" width="1200" height="451" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQ1MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*HpkfNpNAwG8fjJ-Cm9BsUg.png" /></p>

<ul>
  <li>ドリンク注文でパン付き＋単品エビフライバーガー</li>
</ul>

<blockquote>
  <p><em>長距離の移動なので、体力を多めに温存しようと思いました。</em></p>
</blockquote>

<h4 id="1130頃に大通地下鉄駅31番出口の公園でバスを待つ">11:30頃に<a href="https://maps.app.goo.gl/dgPQLs75bVNTbVPR9" target="_blank">大通地下鉄駅31番出口</a>の公園でバスを待つ</h4>

<p><img src="/assets/055527a739dd/1*v4Yooh8ijGwkJw00MO1gMg.webp" alt="" loading="lazy" decoding="async" width="1200" height="452" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQ1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*v4Yooh8ijGwkJw00MO1gMg.png" /></p>

<p><img src="/assets/055527a739dd/1*mc74gZLhUIfqbW49JYgUXw.webp" alt="" loading="lazy" decoding="async" width="960" height="1280" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjAiIGhlaWdodD0iMTI4MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*mc74gZLhUIfqbW49JYgUXw.jpeg" /></p>

<blockquote>
  <p><em>日帰りツアーはほとんどこの公園の周辺で集合するため、自分のグループかどうかガイドに確認しないと、間違ったバスに乗ってしまうことがあります。</em></p>
</blockquote>

<h4 id="1140-ガイドが到着乗車">11:40 ガイドが到着、乗車</h4>

<p><img src="/assets/055527a739dd/1*AFAqnskVajf2pY0py1Bn7w.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*AFAqnskVajf2pY0py1Bn7w.jpeg" /></p>

<p>前回の「<a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E4%B9%9D%E5%B7%9E%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-%E9%87%9C%E5%B1%B1%E6%96%B0%E5%B1%B1%E8%8C%B6%E8%8A%B1%E8%99%9F%E9%83%B5%E8%BC%AA%E5%85%A5%E5%A2%83%E6%97%A5%E6%9C%AC%E5%8D%9A%E5%A4%9A-%E6%B7%B1%E5%85%A5%E7%94%B1%E5%B8%83%E9%99%A2-%E5%A4%A7%E5%88%86-%E7%A6%8F%E5%B2%A1%E7%AD%89%E5%9C%B0-cb65fd5ab770/#day-9-kkday-%E9%AB%98%E5%8D%83%E7%A9%97%E4%B8%80%E6%97%A5%E9%81%8A%E9%AB%98%E5%8D%83%E7%A9%97%E7%A5%9E%E7%A4%BE%E9%AB%98%E5%8D%83%E7%A9%97%E5%B3%BD%E8%B0%B7%E5%A4%A9%E5%B2%A9%E6%88%B8%E7%A5%9E%E7%A4%BE%E5%A4%A9%E5%AE%89%E6%B2%B3%E5%8E%9F" target="_blank">KKDAY 高千穂日帰りツアー、高千穂神社、高千穂峡谷、天岩戸神社、天安河原</a>」では大型バスの運転手兼ガイドでしたが、今回は初めて6人の小グループで、車の運転手兼ガイドのみでした。ただ人数が少ない分、移動が速いのが利点です。</p>

<p><img src="/assets/055527a739dd/1*GGf6O-gDlFpehOsdYEx-vw.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*GGf6O-gDlFpehOsdYEx-vw.jpeg" /></p>

<p>まず高速道路を走り、その後深い山の中の山道に入りますが、本当にかなり遠いです。</p>

<blockquote>
  <p><strong><em>最初の観光地までの所要時間：約1時間50分。</em></strong></p>
</blockquote>

<h4 id="1330-富良野森の妖精テラス-昼間"><a href="https://www.google.com/maps/search/?api=1&amp;query=43.3232668%2C142.3563319&amp;query_place_id=ChIJPbaM-V5Sc18RLOjzIysMtac" target="_blank">13:30 富良野森の妖精テラス-昼間</a></h4>

<p><img src="/assets/055527a739dd/1*2ur7G9_kzOM1MD8eauR0fg.webp" alt="" loading="lazy" decoding="async" width="3122" height="1784" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMTIyIiBoZWlnaHQ9IjE3ODQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*2ur7G9_kzOM1MD8eauR0fg.png" /></p>

<p>ここに観光案内所があり、トイレも利用できます。後ろには富良野スキー場があります。</p>

<p><img src="/assets/055527a739dd/1*7M8YnUnPp4Srks7MyeFIHw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*7M8YnUnPp4Srks7MyeFIHw.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*aJdiFhYD9bY2-DjAjpJxog.webp" alt="" loading="lazy" decoding="async" width="3052" height="2036" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDUyIiBoZWlnaHQ9IjIwMzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*aJdiFhYD9bY2-DjAjpJxog.png" /></p>

<p><img src="/assets/055527a739dd/1*vBRe8LKhvuxUAPJ1YMuVPw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*vBRe8LKhvuxUAPJ1YMuVPw.jpeg" /></p>

<blockquote>
  <p><em>富良野の森の精霊テラスは森の中の木道にあり、多くの小さな木の小屋で手作り商品を販売しています。全体はそれほど大きくなく、一周しても10分以内です。冬は昼間に雪景色が楽しめ、夜はライトアップがあります。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>店舗の入口および店内での撮影は禁止されています。</em></strong></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*Bh5lCi-uhSPsvKmRHxITag.webp" alt="木製の月の手作り記念品を買いました" loading="lazy" decoding="async" width="903" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*Bh5lCi-uhSPsvKmRHxITag.png" /></p>

<p>木製の月の手作り記念品を買いました</p>

<blockquote>
  <p><em>私たちは早めに到着したので、ここで50分間滞在しました。</em></p>
</blockquote>

<h4 id="1420-出発-ハーブガーデン富良野-herb-garden-furanotarget_blank">14:20 出発 ハーブガーデン富良野 (<a href="https://maps.app.goo.gl/kYdVBB1XYsgGo45x7">HERB GARDEN FURANO</a>){:target=”_blank”}</h4>

<blockquote>
  <p><strong><em>車で約30分です。</em></strong></p>
</blockquote>

<blockquote>
  <p><em>休憩所（ショッピングスポット）ツアー、<strong>強制販売なし、中のアイスクリームが美味しい！</strong></em></p>
</blockquote>

<blockquote>
  <p><em>約30分間滞在します。</em></p>
</blockquote>

<h4 id="1540-到着-美瑛駅">15:40 到着 <a href="https://www.google.com/maps/search/?api=1&amp;query=43.5911991%2C142.4633615&amp;query_place_id=ChIJVzdU8tzFDF8RTXvFSGX1S8Y" target="_blank">美瑛駅</a></h4>

<p><img src="/assets/055527a739dd/1*fEsxWXDi675dMyBw-cZnag.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*fEsxWXDi675dMyBw-cZnag.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*kquYhK10b7_hz5ASDgp5gQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="797" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*kquYhK10b7_hz5ASDgp5gQ.png" /></p>

<blockquote>
  <p><a href="https://www.google.com/maps/search/?api=1&amp;query=43.5911991%2C142.4633615&amp;query_place_id=ChIJVzdU8tzFDF8RTXvFSGX1S8Y" target="*blank"><em>美瑛駅</em></a> <em>とても小さく周辺は閑散としており、主に写真を撮ったりトイレに行ったり、<strong>近くで何かを買って夜ご飯に持ち歩くために立ち寄る場所です</strong>。</em></p>
</blockquote>

<blockquote>
  <p><em>近くにセブンイレブンとパン屋があります。</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*e2sqcvDP_rl7hJpTK8FlWQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*e2sqcvDP_rl7hJpTK8FlWQ.jpeg" /></p>

<p>パンとコンビニの惣菜を買って、移動中の夕食にしました。</p>

<blockquote>
  <p><em>約50分間滞在します。</em></p>
</blockquote>

<h4 id="1630-美瑛クリスマスツリーへ出発">16:30 <a href="https://maps.app.goo.gl/5MbFa5QCD46tfjH67" target="_blank">美瑛クリスマスツリー</a>へ出発</h4>

<blockquote>
  <p><em>車で約10分、道沿いの観光スポット。</em></p>
</blockquote>

<h4 id="1640-到着-美瑛クリスマスツリー">16:40 到着 <a href="https://maps.app.goo.gl/5MbFa5QCD46tfjH67" target="_blank">美瑛クリスマスツリー</a></h4>

<p><img src="/assets/055527a739dd/1*VNDn9fdGddz9VJpvUunO_g.webp" alt="" loading="lazy" decoding="async" width="3198" height="2130" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMTk4IiBoZWlnaHQ9IjIxMzAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*VNDn9fdGddz9VJpvUunO_g.png" /></p>

<p><img src="/assets/055527a739dd/1*bmTIWwQmcsnzZoqe0ciDlg.webp" alt="" loading="lazy" decoding="async" width="1477" height="1108" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDc3IiBoZWlnaHQ9IjExMDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*bmTIWwQmcsnzZoqe0ciDlg.jpeg" /></p>

<p>四季それぞれに異なる景色が楽しめますが、今日は夕陽がかすかに見える雪景色です。</p>

<blockquote>
  <p><em>約20分間滞在します。</em></p>
</blockquote>

<h4 id="1700-白ひげの滝へ出発">17:00 <a href="https://www.google.com/maps/search/?api=1&amp;query=43.474803813168%2C142.63934225235&amp;query_place_id=none" target="_blank">白ひげの滝</a>へ出発</h4>

<blockquote>
  <p><em>車で約30分、橋の観光スポット。</em></p>
</blockquote>

<h4 id="1730-到着-白髭の滝">17:30 到着 <a href="https://www.google.com/maps/search/?api=1&amp;query=43.474803813168%2C142.63934225235&amp;query_place_id=none" target="_blank">白髭の滝</a></h4>

<p><img src="/assets/055527a739dd/1*dDpDKI44Mek6JN6zFChEhA.webp" alt="" loading="lazy" decoding="async" width="1200" height="683" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY4MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*dDpDKI44Mek6JN6zFChEhA.png" /></p>

<p>この歩道橋から下を見ると、凍った白ひげの滝が見えます。</p>

<p><img src="/assets/055527a739dd/1*tiviDULpwjoqXcl4kcncfw.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*tiviDULpwjoqXcl4kcncfw.jpeg" /></p>

<blockquote>
  <p><em>約20分間滞在します。</em></p>
</blockquote>

<blockquote>
  <p><em>夕方に近づき、天気は寒いです；<strong>橋の上は凍っているので歩くときは注意してください</strong>。</em></p>
</blockquote>

<h4 id="1750-白金青池へ出発">17:50 <a href="https://www.google.com/maps/search/?api=1&amp;query=43.493606086454%2C142.61433241373&amp;query_place_id=none" target="_blank">白金青池</a>へ出発</h4>

<blockquote>
  <p><em>車で約5分です。</em></p>
</blockquote>

<h4 id="1755-最後のスポット-白金青池-に到着">17:55 最後のスポット <a href="https://www.google.com/maps/search/?api=1&amp;query=43.493606086454%2C142.61433241373&amp;query_place_id=none" target="_blank">白金青池</a> に到着</h4>

<p><img src="/assets/055527a739dd/1*E9VIGAECznfFqG9QKyRqBA.webp" alt="" loading="lazy" decoding="async" width="2160" height="2172" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMTYwIiBoZWlnaHQ9IjIxNzIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*E9VIGAECznfFqG9QKyRqBA.png" /></p>

<blockquote>
  <p><em>約30分間滞在し、観光案内所にトイレがあります。</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*l61TfdQcTz-adTlROZsmnA.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*l61TfdQcTz-adTlROZsmnA.jpeg" /></p>

<p>駐車場から上に歩くと青い池が見えます。</p>

<p><img src="/assets/055527a739dd/1*1g4Qki4CDbE4WWOoNig2Rg.webp" alt="" loading="lazy" decoding="async" width="2048" height="1536" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDQ4IiBoZWlnaHQ9IjE1MzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*1g4Qki4CDbE4WWOoNig2Rg.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*68bEAmSijcpqQbGn8z58lA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*68bEAmSijcpqQbGn8z58lA.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*b92j-p7ghCGyP3peml3M3A.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*b92j-p7ghCGyP3peml3M3A.jpeg" /></p>

<blockquote>
  <p><em>静かなスポットであり、凍った池の表面が光と影の変化を通じて一筋の生命力を見せている。</em></p>
</blockquote>

<h4 id="1830-帰路-大通地下鉄駅-31番出口">18:30 帰路 <a href="https://maps.app.goo.gl/dgPQLs75bVNTbVPR9" target="_blank">大通地下鉄駅 31番出口</a></h4>

<p><img src="/assets/055527a739dd/1*VwEV_rxTwap-JzHlqs4kMw.webp" alt="" loading="lazy" decoding="async" width="2048" height="1536" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDQ4IiBoZWlnaHQ9IjE1MzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*VwEV_rxTwap-JzHlqs4kMw.jpeg" /></p>

<blockquote>
  <p><em>車での所要時間：約2時間30分、途中20:00頃に休憩所を通過し、トイレ休憩があります。</em></p>
</blockquote>

<h4 id="2055-到着-大通駅-地下鉄31番出口">20:55 到着 <a href="https://maps.app.goo.gl/dgPQLs75bVNTbVPR9" target="_blank">大通駅 地下鉄31番出口</a></h4>

<p>全体的には以前の「<a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E4%B9%9D%E5%B7%9E%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-%E9%87%9C%E5%B1%B1%E6%96%B0%E5%B1%B1%E8%8C%B6%E8%8A%B1%E8%99%9F%E9%83%B5%E8%BC%AA%E5%85%A5%E5%A2%83%E6%97%A5%E6%9C%AC%E5%8D%9A%E5%A4%9A-%E6%B7%B1%E5%85%A5%E7%94%B1%E5%B8%83%E9%99%A2-%E5%A4%A7%E5%88%86-%E7%A6%8F%E5%B2%A1%E7%AD%89%E5%9C%B0-cb65fd5ab770/#day-9-kkday-%E9%AB%98%E5%8D%83%E7%A9%97%E4%B8%80%E6%97%A5%E9%81%8A%E9%AB%98%E5%8D%83%E7%A9%97%E7%A5%9E%E7%A4%BE%E9%AB%98%E5%8D%83%E7%A9%97%E5%B3%BD%E8%B0%B7%E5%A4%A9%E5%B2%A9%E6%88%B8%E7%A5%9E%E7%A4%BE%E5%A4%A9%E5%AE%89%E6%B2%B3%E5%8E%9F" target="_blank">KKDAY 高千穂一日ツアー、高千穂神社、高千穂峡谷、天岩戸神社、天安河原</a>」の感想とほぼ同じで、バスに乗って駆け足で回る感じです。自分でこれらの観光地に行くのは非常に面倒で、道の半分は高速道路、半分は山道の無人地帯（熊が多そうな感じ）です。今回は小グループの行動で、しかも運転手が飛ばしたため、予定より早く市街地に戻りました。</p>

<h4 id="2130-札幌駅に戻る">21:30 札幌駅に戻る</h4>

<p>大通駅周辺を少し散策した後、札幌駅に戻りました。ほとんどの飲食店は閉店していました。</p>

<h4 id="札幌-つなぐ-横町"><a href="https://maps.app.goo.gl/kWrKsjCDcQXqZ7MW6" target="_blank"><strong>札幌 つなぐ 横町</strong></a></h4>

<p>駅の近くに夜市がまだ営業しているのを調べて、ぶらっと見に行きました。何でもいいので、何か食べようと思って。</p>

<p><img src="/assets/055527a739dd/1*PthAxfmCvDvVAb1A96Xxcw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*PthAxfmCvDvVAb1A96Xxcw.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*chm5p8whKi2G8nLTCbNu1Q.webp" alt="" loading="lazy" decoding="async" width="3516" height="1996" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTE2IiBoZWlnaHQ9IjE5OTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*chm5p8whKi2G8nLTCbNu1Q.png" /></p>

<p>適当に串焼き（主に鰻の串焼き）がある店を選んで、まず少し食べました。</p>

<blockquote>
  <p><em>この店も3月までの営業で、手羽先を食べたかったのに、間違った店を選んでしまった。</em></p>
</blockquote>

<h4 id="2230-ホテルに戻る">22:30 ホテルに戻る</h4>

<p><img src="/assets/055527a739dd/1*iVNNjGw0DokpzTnl6XKUyg.webp" alt="" loading="lazy" decoding="async" width="3038" height="1730" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDM4IiBoZWlnaHQ9IjE3MzAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*iVNNjGw0DokpzTnl6XKUyg.png" /></p>

<p>食事の後、まだ少しお腹が空いていたので、近くのコンビニで夜食を買って帰りました。</p>

<blockquote>
  <p>S <em>eicomart には Lawsone/711/ファミリーマートにはない商品が売っています。</em></p>
</blockquote>

<h3 id="day-5-0319-木-ショッピングと北海道神宮">Day 5 (03/19 木) —ショッピングと北海道神宮</h3>

<h4 id="1000-朝食を食べに出発-マクドナルド">10:00 朝食を食べに出発 <a href="https://maps.app.goo.gl/3xn9SZskRd8Yzr2t9" target="_blank">マクドナルド</a></h4>

<p><img src="/assets/055527a739dd/1*38MT4SC9vjfjZBJua2NE1A.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*38MT4SC9vjfjZBJua2NE1A.jpeg" /></p>

<p><img src="/assets/055527a739dd/1*kODLJ4LXRV_ZXVa20qwZNg.webp" alt="" loading="lazy" decoding="async" width="1200" height="799" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*kODLJ4LXRV_ZXVa20qwZNg.png" /></p>

<ul>
  <li>
    <p>McGriddles ホットケーキサンド（台湾では販売なし）— ベーコンチーズエッグ、ハチミツの甘じょっぱい味</p>
  </li>
  <li>
    <p>ストロベリーチーズパイ（台湾でも後に販売開始）— ストロベリージャム＋チーズ</p>
  </li>
</ul>

<h4 id="1000-大通り-狸小路でガチャガチャを続ける-ドンキホーテ-で買い物">10:00 大通り 狸小路でガチャガチャを続ける <a href="https://maps.app.goo.gl/t9UREfvkAkyNrCim6" target="_blank">、ドン・キホーテ</a> で買い物</h4>

<p><img src="/assets/055527a739dd/1*7TSlQ_cHD2h9sBSh_w1XVQ.webp" alt="" loading="lazy" decoding="async" width="3654" height="2084" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNjU0IiBoZWlnaHQ9IjIwODQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*7TSlQ_cHD2h9sBSh_w1XVQ.png" /></p>

<p><img src="/assets/055527a739dd/1*B9w_5kkFC02FeDDpl49I_Q.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*B9w_5kkFC02FeDDpl49I_Q.jpeg" /></p>

<blockquote>
  <p><em>札幌駅はあまり見るところがなく、こちらの方が色々と見て回れます。</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*ATM-ffFeXSn1OU2MsF1VYw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*ATM-ffFeXSn1OU2MsF1VYw.jpeg" /></p>

<p>火災報知器のガチャガチャといくつか面白いガチャガチャ。</p>

<h4 id="1330-札幌駅のホテルに荷物を置いてデパートで引き続き食べ歩き">13:30 札幌駅のホテルに荷物を置いて、デパートで引き続き食べ歩き</h4>

<p><img src="/assets/055527a739dd/1*WlIAL89mRGqmZUHBO6zqTg.webp" alt="昼食はデパートのちらし寿司とそばを適当に食べました" loading="lazy" decoding="async" width="4117" height="3093" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MTE3IiBoZWlnaHQ9IjMwOTMiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*WlIAL89mRGqmZUHBO6zqTg.png" /></p>

<p>昼食はデパートのバラ寿司＋そばを適当に食べました。</p>

<h4 id="le-labo-ル-ラボ-札幌大丸店"><a href="https://maps.app.goo.gl/fdeQ5DFzfkGPGgaQ8" target="_blank">LE LABO ル ラボ 札幌大丸店</a></h4>

<p>ついでに Le Labo 2026 / 札幌での購入価格をチェック：</p>

<p><img src="/assets/055527a739dd/1*Q039ga_Vw3MQgF0g0BRqwA.webp" alt="" loading="lazy" decoding="async" width="1086" height="1013" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDg2IiBoZWlnaHQ9IjEwMTMiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*Q039ga_Vw3MQgF0g0BRqwA.png" /></p>

<ul>
  <li>50ml ¥31,350 と <a href="/posts/z-度旅行遊記/東京近郊自由行-川越小江戸-熱海海上花火大会5日間完全ガイド-958599363857/">2025年東京の価格と同じ</a></li>
</ul>

<blockquote>
  <p><em>買い物を楽しんだ後、15:00頃に<a href="https://maps.app.goo.gl/sZDHVC7X3ctkwQzX9" target="_blank">北海道神宮</a>へ出発しました。</em></p>
</blockquote>

<blockquote>
  <p><em>札幌から南北線で大通駅まで行き、東西線に乗り換えて<a href="https://maps.app.goo.gl/rhiPPKBaugwZBxid6" target="_blank">円山公園駅</a>へ。所要時間は約30分。</em></p>
</blockquote>

<h4 id="1540-円山公園駅に到着">15:40 <a href="https://maps.app.goo.gl/rhiPPKBaugwZBxid6" target="_blank">円山公園駅</a>に到着</h4>

<p><img src="/assets/055527a739dd/1*UVfaLNsp7YdujXBEEzQHCQ.webp" alt="" loading="lazy" decoding="async" width="1858" height="2490" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxODU4IiBoZWlnaHQ9IjI0OTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*UVfaLNsp7YdujXBEEzQHCQ.png" /></p>

<blockquote>
  <p><em>もし早めに行ければ、近くの<a href="https://maps.app.goo.gl/jZe1NSebYoACZfEj8" target="_blank"><strong>有名な北海道の回転寿司 Toriton</strong></a>に先に行くことができます</em> 。</p>
</blockquote>

<blockquote>
  <p><em>円山公園駅3番出口を出て、公園の方向にまっすぐ進むと北海道神宮に着きます。</em></p>
</blockquote>

<blockquote>
  <p><em>所要時間：約850メートル / 15分</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*S002OiQvL92tuOKH1IdGkg.webp" alt="" loading="lazy" decoding="async" width="1200" height="801" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*S002OiQvL92tuOKH1IdGkg.png" /></p>

<p>横断歩道を渡るとすぐに公園の入口です：</p>

<p><img src="/assets/055527a739dd/1*D8BbsmFeID8pc06a0JjeTw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*D8BbsmFeID8pc06a0JjeTw.jpeg" /></p>

<blockquote>
  <p><em>友達と円山で待ち合わせするとき…</em></p>
</blockquote>

<blockquote>
  <p><em>私：円山公園 💁</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*xqB_Gf70oekdjB_7kAlyUw.webp" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*xqB_Gf70oekdjB_7kAlyUw.png" /></p>

<p>まず円山公園を通り抜けます（ここにはまだ多くの積雪があります）、すると神宮の鳥居の入口が見えます：</p>

<p><img src="/assets/055527a739dd/1*cBmTSlECefOGTo6xrR-uLA.webp" alt="" loading="lazy" decoding="async" width="3092" height="4117" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDkyIiBoZWlnaHQ9IjQxMTciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*cBmTSlECefOGTo6xrR-uLA.png" /></p>

<h4 id="1550-神宮茶屋"><a href="https://maps.app.goo.gl/A4X2vpZic2F3onHD9" target="_blank">15:50 神宮茶屋</a></h4>

<p><img src="/assets/055527a739dd/1*cDFq2pN_R-mdNkjb9J6M2Q.webp" alt="" loading="lazy" decoding="async" width="1128" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTI4IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*cDFq2pN_R-mdNkjb9J6M2Q.png" /></p>

<p>歩いて行くと神宮茶屋を通るので、まず北海道ミルクのアイスクリームを食べに行きます。</p>

<p><img src="/assets/055527a739dd/1*ak0-XC8XNs7U80Jv7w0SHw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*ak0-XC8XNs7U80Jv7w0SHw.jpeg" /></p>

<p>とても濃厚で美味しい。</p>

<blockquote>
  <p><strong><em>神宮内での飲食は禁止されています。茶屋で食事を済ませてから移動しましょう。</em></strong></p>
</blockquote>

<h4 id="1615-北海道神宮"><a href="https://maps.app.goo.gl/sZDHVC7X3ctkwQzX9" target="_blank">16:15 北海道神宮</a></h4>

<p><img src="/assets/055527a739dd/1*geeJcHKwKdulE3ZAKdrdXw.webp" alt="" loading="lazy" decoding="async" width="1698" height="1236" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNjk4IiBoZWlnaHQ9IjEyMzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*geeJcHKwKdulE3ZAKdrdXw.png" /></p>

<blockquote>
  <p><em>参拝：<strong>五円玉を投げる（縁結びの意味）-&gt; 二回お辞儀 -&gt; 二回拍手 -&gt; 願い事をする -&gt; 最後に一回お辞儀</strong></em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*vIk2569WTqkQU_EOFagzkA.webp" alt="" loading="lazy" decoding="async" width="2826" height="1484" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyODI2IiBoZWlnaHQ9IjE0ODQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*vIk2569WTqkQU_EOFagzkA.png" /></p>

<p><img src="/assets/055527a739dd/1*Mvgp7m0K3DkGJTemBXAIEw.webp" alt="" loading="lazy" decoding="async" width="1974" height="1484" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOTc0IiBoZWlnaHQ9IjE0ODQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*Mvgp7m0K3DkGJTemBXAIEw.png" /></p>

<p>お守りを二つ買いました。特に珍しいのは交通安全のお守りで、車内に掛けられるものと、バイク、自転車、ヘルメットに貼れるステッカーがあります。</p>

<h4 id="1630-北海道神宮を出発">16:30 北海道神宮を出発</h4>

<p><img src="/assets/055527a739dd/1*uf7nqGUX9f_Sx-RWSieeSQ.webp" alt="" loading="lazy" decoding="async" width="3260" height="2170" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMjYwIiBoZWlnaHQ9IjIxNzAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*uf7nqGUX9f_Sx-RWSieeSQ.png" /></p>

<p>神宮と公園からゆっくり歩いて地下鉄駅へ向かい、札幌駅周辺で夕食を食べる準備をしました。</p>

<h3 id="1720-札幌北海道庁赤レンガ庁舎を通過">17:20 <a href="https://maps.app.goo.gl/TPopSdeEizc4L3pt9" target="_blank">札幌北海道庁赤レンガ庁舎を通過</a></h3>

<p><img src="/assets/055527a739dd/1*HepNYeLKdeZnUDG-5z9OjA.webp" alt="" loading="lazy" decoding="async" width="1536" height="2048" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNTM2IiBoZWlnaHQ9IjIwNDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*HepNYeLKdeZnUDG-5z9OjA.jpeg" /></p>

<p>ただ通りかかっただけで、主に隣の札幌三井で焼肉を食べに行きました：</p>

<p><img src="/assets/055527a739dd/1*0q_FfJh3NGkGSK2Qy3R0Yg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*0q_FfJh3NGkGSK2Qy3R0Yg.jpeg" /></p>

<h3 id="1730-焼肉バル田村-焼肉"><a href="https://maps.app.goo.gl/G8HjR4dNjvcoLA246" target="_blank">17:30 焼肉バル田村</a> 焼肉</h3>

<p><img src="/assets/055527a739dd/1*VNc3gye9wK6y56eHPc2deA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*VNc3gye9wK6y56eHPc2deA.jpeg" /></p>

<p>北海道和牛を試してみましょう。</p>

<p><img src="/assets/055527a739dd/1*AYwFzwBblluHK6-hmf_Cfw.webp" alt="" loading="lazy" decoding="async" width="3458" height="1640" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNDU4IiBoZWlnaHQ9IjE2NDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*AYwFzwBblluHK6-hmf_Cfw.png" /></p>

<blockquote>
  <p><em>北海道牛セット＋サラダ＋ビール＋ドリンク＋冷麺を注文し、合計で約NT$3,100でした。和牛は脂が豊富で口の中でとろけ、ステーキも美味しかったですが、一番驚いたのは牛タンで、とても弾力があり美味しかったです。</em></p>
</blockquote>

<h4 id="1900-札幌東急百貨店"><a href="https://maps.app.goo.gl/rR4a14JofuNjSBXT8" target="_blank">19:00 札幌東急百貨店</a></h4>

<p><img src="/assets/055527a739dd/1*M1Jvj4MqsexEZInEN2CYiw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*M1Jvj4MqsexEZInEN2CYiw.jpeg" /></p>

<p>お腹がいっぱいになった後、最後に東急百貨店を訪れました。</p>

<p><img src="/assets/055527a739dd/1*ruyLfADnDmXwM1iObk1rig.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*ruyLfADnDmXwM1iObk1rig.jpeg" /></p>

<p>こちらの上の階にもおもちゃやガチャガチャがあります。</p>

<h4 id="2000-札幌駅に戻る">20:00 札幌駅に戻る</h4>

<p><img src="/assets/055527a739dd/1*Qm2l3HH2jAG788N4lvMRDA.webp" alt="" loading="lazy" decoding="async" width="901" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDEiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*Qm2l3HH2jAG788N4lvMRDA.png" /></p>

<p>デパートがもうすぐ閉店するので、最後にもう一度見て回ります。</p>

<h4 id="札幌駅--サンドイッチ工房-sandria"><a href="https://www.s-sandwich.com/" target="_blank">札幌駅 — サンドイッチ工房 Sandria</a></h4>

<p><img src="/assets/055527a739dd/1*6d-W6JOQaseQid4b7YrKow.webp" alt="" loading="lazy" decoding="async" width="1200" height="686" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY4NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*6d-W6JOQaseQid4b7YrKow.png" /></p>

<p>ホテルに戻る途中、毎日通るJR駅で多くの人が並んでいるサンドイッチの自動販売機で買いました。</p>

<blockquote>
  <p><em>お一人様2個まで購入可能で、私はとんかつを夜食に、ポテトと卵のサラダを翌朝の朝食用に買いました。</em></p>
</blockquote>

<h4 id="2230-札幌での最後の夜の夜食">22:30 札幌での最後の夜の夜食</h4>

<p><img src="/assets/055527a739dd/1*RUURJltr-9QnEkSuGXEsUA.webp" alt="" loading="lazy" decoding="async" width="3552" height="2020" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTUyIiBoZWlnaHQ9IjIwMjAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*RUURJltr-9QnEkSuGXEsUA.png" /></p>

<blockquote>
  <p>初日に飲んだイチゴ酒と北海道ミルクアイスクリーム。</p>
</blockquote>

<h3 id="day-6-0320-金--新千歳空港帰路">Day 6 (03/20 金) — 新千歳空港、帰路</h3>

<h4 id="1000-起床して部屋で朝食を食べる">10:00 起床して部屋で朝食を食べる</h4>

<p><img src="/assets/055527a739dd/1*O6AlKj2q5BGnpifN8xfb1Q.webp" alt="" loading="lazy" decoding="async" width="2048" height="1536" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDQ4IiBoZWlnaHQ9IjE1MzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*O6AlKj2q5BGnpifN8xfb1Q.jpeg" /></p>

<p>食事を終えて片付けたら、チェックアウトしてそのまま空港へ向かいました。</p>

<h4 id="1105-札幌駅でバス待ち">11:05 札幌駅でバス待ち</h4>

<p><img src="/assets/055527a739dd/1*NZDX273R7I57ua8K7dgQZg.webp" alt="" loading="lazy" decoding="async" width="1200" height="728" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjcyOCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*NZDX273R7I57ua8K7dgQZg.png" /></p>

<h4 id="1119-札幌駅から新千歳空港へ向かうために乗車">11:19 札幌駅から新千歳空港へ向かうために乗車</h4>

<blockquote>
  <p><em>快速エアポート68快速新千歳空港、38分</em></p>
</blockquote>

<h4 id="1200-新千歳空港に到着">12:00 新千歳空港に到着</h4>

<p><img src="/assets/055527a739dd/1*GY04A3vbPbQHK3yCnjUSyw.webp" alt="" loading="lazy" decoding="async" width="958" height="1115" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTgiIGhlaWdodD0iMTExNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*GY04A3vbPbQHK3yCnjUSyw.png" /></p>

<h4 id="jr-新千歳空港国内線ロビー">JR 新千歳空港、国内線ロビー</h4>

<p><img src="/assets/055527a739dd/1*gh59koOOU8_OF3ONpsXV-g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*gh59koOOU8_OF3ONpsXV-g.jpeg" /></p>

<blockquote>
  <p><em>地下鉄で1階のロビーに上がると、多くの飲食店やお土産屋があります。もし買い足りなければ、ここでさらに買い物ができます。</em></p>
</blockquote>

<h4 id="帰る時間に来た道をそのまま戻る">帰る時間に…来た道をそのまま戻る</h4>

<p><img src="/assets/055527a739dd/1*6W0gH8pkfaj0OJyXMEdLbQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*6W0gH8pkfaj0OJyXMEdLbQ.jpeg" /></p>

<h4 id="1217-国際線ロビーに到着">12:17 国際線ロビーに到着</h4>

<p><img src="/assets/055527a739dd/1*7WibQith1SFr80NzDbpVpw.webp" alt="" loading="lazy" decoding="async" width="1704" height="1179" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNzA0IiBoZWlnaHQ9IjExNzkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*7WibQith1SFr80NzDbpVpw.png" /></p>

<p>一番端のカウンターに割り当てられ、到着するまでに165メートル歩きます：</p>

<p><img src="/assets/055527a739dd/1*s5JrKPKZCS7aalLWzJzQAQ.webp" alt="" loading="lazy" decoding="async" width="961" height="772" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjEiIGhlaWdodD0iNzcyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/055527a739dd/1*s5JrKPKZCS7aalLWzJzQAQ.png" /></p>

<p>北海道トリギンノドナガオヤマガラ：</p>

<p><img src="/assets/055527a739dd/1*vfgtjZcmirVzk2On2jCiaA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*vfgtjZcmirVzk2On2jCiaA.jpeg" /></p>

<h4 id="1222-チェックインカウンターに到着">12:22 チェックインカウンターに到着</h4>

<blockquote>
  <p><em>現地は混雑しており、オンラインチェックインを利用する人は少ないため、必ず帰路の<a href="https://calec.china-airlines.com/eCheckin/eCheckin_home.aspx" target="_blank">3日前までに座席指定とオンラインチェックインを完了し、待ち時間を節約しましょう。</a></em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*Kf8mo1c0_Q_dCgUF3cYV-g.webp" alt="" loading="lazy" decoding="async" width="1200" height="835" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgzNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*Kf8mo1c0_Q_dCgUF3cYV-g.png" /></p>

<p>こちらの後ろにドン・キホーテがあり、荷物を預ける前の最後の買い物ができます：</p>

<p><img src="/assets/055527a739dd/1*Nh4v3mOEt0UkPi9ERBJ8yw.webp" alt="" loading="lazy" decoding="async" width="1200" height="833" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgzMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*Nh4v3mOEt0UkPi9ERBJ8yw.png" /></p>

<h4 id="1303-チェックインと荷物預け完了">13:03 チェックインと荷物預け完了</h4>

<h4 id="1317-セキュリティチェックと出国審査完了">13:17 セキュリティチェックと出国審査完了</h4>

<blockquote>
  <p><em>日本の空港の保安検査は厳しく、ブーツを履いている場合は必ず脱いでX線検査を受ける必要があります。</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*KEoEKjL5F66qscCtVKyLcw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*KEoEKjL5F66qscCtVKyLcw.jpeg" /></p>

<h4 id="1320-搭乗待ちの間に散策">13:20 搭乗待ちの間に散策</h4>

<p><img src="/assets/055527a739dd/1*jYqkVX8z5aFrCMr9LD7vlQ.webp" alt="" loading="lazy" decoding="async" width="3322" height="1064" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMzIyIiBoZWlnaHQ9IjEwNjQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*jYqkVX8z5aFrCMr9LD7vlQ.png" /></p>

<p><img src="/assets/055527a739dd/1*vwC7ieofFNIOVl2L_0YjKA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*vwC7ieofFNIOVl2L_0YjKA.jpeg" /></p>

<blockquote>
  <p><em>飲食店街があり、私はパン、唐揚げ、メロンアイスだけ買って少し食べました。</em></p>
</blockquote>

<p><img src="/assets/055527a739dd/1*_83IZv2r6TiRQW-isqq3iw.webp" alt="" loading="lazy" decoding="async" width="1200" height="833" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgzMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*_83IZv2r6TiRQW-isqq3iw.png" /></p>

<p>1階にはお土産店がずらりと並んでいて、ほとんど何でも買えますが、ブランドショップは少なめです。</p>

<p><img src="/assets/055527a739dd/1*5UHmAXCqA7_aR5EeHTvWzg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*5UHmAXCqA7_aR5EeHTvWzg.jpeg" /></p>

<p>2階にもいくつかのお土産があります。</p>

<h4 id="1430-搭乗手続き完了">14:30 搭乗手続き完了</h4>

<p><img src="/assets/055527a739dd/1*ggFHkcOkMXJO-u8Opfn1lw.webp" alt="" loading="lazy" decoding="async" width="1200" height="802" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*ggFHkcOkMXJO-u8Opfn1lw.png" /></p>

<p>来た時と同じく新しいエアバス機で、座席が広く、エンターテインメント設備も新しいです。</p>

<h4 id="1500-出発さようなら--札幌">15:00 出発、さようなら — 札幌</h4>

<p><img src="/assets/055527a739dd/1*NsbLIJ-RuRa4YOkVICnPGA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*NsbLIJ-RuRa4YOkVICnPGA.jpeg" /></p>

<p>機内食は相変わらず普通でした：</p>

<p><img src="/assets/055527a739dd/1*a20WxDinpEcoDIUd6Bi3xw.webp" alt="" loading="lazy" decoding="async" width="2048" height="1536" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDQ4IiBoZWlnaHQ9IjE1MzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*a20WxDinpEcoDIUd6Bi3xw.jpeg" /></p>

<h4 id="1815-台湾桃園国際空港に到着">18:15 台湾桃園国際空港に到着</h4>

<h4 id="1915-入国荷物受取帰宅して休息">19:15 入国＋荷物受取、帰宅して休息</h4>

<p>今回の荷物はとても長く待ちました…</p>

<h3 id="ご覧いただきありがとうございます">ご覧いただきありがとうございます</h3>

<p>ここまでお読みいただきありがとうございます。北海道のさまざまな風景を一緒に体験しましょう。次の場所でまたお会いしましょう！</p>

<h3 id="機内無料wifi">機内無料WiFi</h3>

<p><img src="/assets/055527a739dd/1*lK1NDVwT4V1iu0XiZhUtsw.webp" alt="" loading="lazy" decoding="async" width="1120" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTIwIiBoZWlnaHQ9IjEyMDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*lK1NDVwT4V1iu0XiZhUtsw.png" /></p>

<p>この便ではチャイナエアラインが全行程でメッセージ用WiFi機能を提供しており、友達とメッセージのやり取りができます。</p>

<blockquote>
  <p><strong><em>もしスマホにAdGuard DNSや類似のDNS広告ブロックサービスを導入している場合は、設定 → 一般 → VPNとデバイス管理 → 制限とプロキシサーバー → DNS → 自動に戻す必要があります。</em></strong></p>
</blockquote>

<blockquote>
  <p><em>そうしないと機内WiFiに接続できません。</em></p>
</blockquote>

<h3 id="戦利品">戦利品</h3>

<p><img src="/assets/055527a739dd/1*zSYwjAvHNp4zYYXixRVExA.webp" alt="" loading="lazy" decoding="async" width="3238" height="2432" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMjM4IiBoZWlnaHQ9IjI0MzIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/055527a739dd/1*zSYwjAvHNp4zYYXixRVExA.png" /></p>

<ul>
  <li>札幌農学校（ミルククッキー）、焼きとうもろこしスナック（膨化）もおすすめです。</li>
</ul>

<h4 id="おもちゃ">おもちゃ</h4>

<p><img src="/assets/055527a739dd/1*Q4kKEs40fKLCm6dfF0LG7Q.webp" alt="" loading="lazy" decoding="async" width="1200" height="901" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/055527a739dd/1*Q4kKEs40fKLCm6dfF0LG7Q.png" /></p>

<ul>
  <li>
    <p>踏切のハンドル、看板のライト、車の鍵、火災報知器、ドン・キホーテのキャラクター、日本代表チームのユニフォーム</p>
  </li>
  <li>
    <p>富良野の精霊台で購入した木製の手作り楽器</p>
  </li>
</ul>

<p><em><a href="https://medium.com/ztravel/%E9%81%8A%E8%A8%98-2026-%E5%8C%97%E6%B5%B7%E9%81%93%E6%9C%AD%E5%B9%8C-6-%E6%97%A5%E9%81%8A-%E6%9C%AD%E5%B9%8C%E5%B8%82%E5%8D%80-%E5%AE%9A%E5%B1%B1%E6%BA%AA%E6%BA%AB%E6%B3%89-%E5%8C%97%E6%B5%B7%E9%81%93%E9%BB%9E%E7%87%88-%E5%AF%8C%E8%89%AF%E9%87%8E%E7%B2%BE%E9%9D%88%E5%8F%B0-%E7%BE%8E%E7%91%9B%E9%9D%92%E6%B1%A0-%E4%B8%80%E6%97%A5%E9%81%8A-055527a739dd" target="_blank">投稿</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>で変換。</em></p>]]></content>
  </entry><entry>
    <title type="html">iOS Certificates, Identifiers &amp;amp; Profilesの関係｜Fastlane Matchで憑證管理とCI/CDを効率化</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ios-certificates-identifiers-profiles%E3%81%AE%E9%96%A2%E4%BF%82-fastlane-match%E3%81%A7%E6%86%91%E8%AD%89%E7%AE%A1%E7%90%86%E3%81%A8ci-cd%E3%82%92%E5%8A%B9%E7%8E%87%E5%8C%96-823ac523ccc8/" rel="alternate" type="text/html" title="iOS Certificates, Identifiers &amp; Profilesの関係｜Fastlane Matchで憑證管理とCI/CDを効率化" />
    <published>2026-01-04T01:03:46+08:00</published>
    <updated>2026-01-05T08:55:47+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/823ac523ccc8</id><summary type="html">iOS開発者向けにCertificates, Identifiers &amp; Profilesの関係性を明確化し、Fastlane Matchで証明書を一元管理。CI/CD統合で手動作業を削減し、開発効率を大幅向上させる方法を具体的に紹介。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="iosアプリ開発" /><category term="fastlane" /><category term="キーチェーン" /><category term="github-actions" /><category term="macos" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/823ac523ccc8/1*-OS8G9xu0CFpnlAQRgnGAg.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ios-certificates-identifiers-profiles%E3%81%AE%E9%96%A2%E4%BF%82-fastlane-match%E3%81%A7%E6%86%91%E8%AD%89%E7%AE%A1%E7%90%86%E3%81%A8ci-cd%E3%82%92%E5%8A%B9%E7%8E%87%E5%8C%96-823ac523ccc8/"><![CDATA[<h3 id="ios-certificatesidentifiers--profiles-とは何かと-fastlane-match-による統一管理-証明書と-cicd-に関するメモ">iOS Certificates、Identifiers &amp; Profiles とは何かと <strong>Fastlane Match による統一管理</strong> <strong>証明書と CI/CD に関するメモ</strong></h3>

<p>Certificates、Identifiers、Profiles の関係と Fastlane Match を使った証明書の一元管理および CI/CD ワークフローへの統合についての記録。</p>

<p><img src="/assets/823ac523ccc8/1*-OS8G9xu0CFpnlAQRgnGAg.webp" alt="Photo by marcos mayer" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/823ac523ccc8/1*-OS8G9xu0CFpnlAQRgnGAg.jpeg" /></p>

<p>Photo by <a href="https://unsplash.com/@mmayyer?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" target="_blank">marcos mayer</a></p>

<h4 id="前書き">前書き</h4>

<p>2025年中に、GitHub Actionsを使ってゼロからアプリのCI/CDの完全な構築プロセスを解説したシリーズ記事を書きました：</p>

<ul>
  <li>
    <p><a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/">CI/CD 実践ガイド（1）：CI/CD とは？CI/CD を使って安定かつ効率的な開発チームを作るには？ツールの選び方は？</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/">CI/CD 実践ガイド（二）：GitHub Actions と self-hosted Runner の使用と構築大全</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/">CI/CD 実践ガイド（三）：GitHub Actions を使ったアプリプロジェクトの CI と CD ワークフローの実装</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/">CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</a></p>
  </li>
</ul>

<p>最近新しい環境で再度実行しましたが、毎回新しいことを学んでいます。今回は iOS のコードサイニング：Certificates / Profiles / Devices の関係に焦点を当て、Fastlane Match を使って証明書管理と CI/CD を連携させる方法についてです。</p>

<h3 id="certificates-identifiers--profilesdevicesとは何ですか"><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Certificates, Identifiers &amp; Profiles、Devicesとは何ですか？</a></h3>

<p>Apple エコシステムでは、アプリ開発は証明書とプロビジョニングプロファイルの管理に基づいており、Android のように .apk ファイルがあればインストールして使えるわけではありません。Apple は厳格な証明書の対応管理を行っており、規則に合わないものはインストールや使用ができません。</p>

<h4 id="主な項目の構成と機能"><strong>主な項目の構成と機能：</strong></h4>

<p><img src="/assets/823ac523ccc8/1*PyM0l-jXXcVBKubOwCiTsw.webp" alt="" loading="lazy" decoding="async" width="1200" height="439" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQzOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/823ac523ccc8/1*PyM0l-jXXcVBKubOwCiTsw.png" /></p>

<h4 id="certificates-アプリ署名の身分-signing-identity"><strong>Certificates:</strong> アプリ署名の身分 (Signing Identity)</h4>

<ul>
  <li>
    <p><strong>Development</strong> — 開発段階で実機で使用（シミュレーターのみの場合は証明書不要）、所有者は個人またはAPIキー（数に制限あり）。</p>
  </li>
  <li>
    <p><strong>Distribution</strong> — App Store、TestFlight、または Ad Hoc 配布（登録済みデバイス限定）に使用、数に制限があり、所属はチーム。</p>
  </li>
  <li>
    <p><strong>Enterprise</strong> — 企業内アプリ用。</p>
  </li>
</ul>

<blockquote>
  <p><strong><em>フォーマット</em></strong> <em>：使用するには <code class="language-plaintext highlighter-rouge">Private Key（秘密鍵）</code> と <code class="language-plaintext highlighter-rouge">Certificate .cer（公開鍵証明書）</code> が必要です。または、元の作成したパソコンの Keychain から <code class="language-plaintext highlighter-rouge">.p12</code> ファイルとしてエクスポートすると、両方が含まれます。</em></p>
</blockquote>

<p><img src="/assets/823ac523ccc8/1*oP_p2kJ1Prqku4D8LIZ7yg.webp" alt="" loading="lazy" decoding="async" width="371" height="115" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNzEiIGhlaWdodD0iMTE1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/823ac523ccc8/1*oP_p2kJ1Prqku4D8LIZ7yg.png" /></p>

<h4 id="identifiers-どの-appextension-bundle-id"><strong>Identifiers: どの App/Extension (Bundle ID)</strong></h4>

<p>App の Bundle ID 登録と有効にする必要がある Capabilities（例：Push Notifications、App Groups の有効化など）、および App Services。</p>

<p>Extension も独自の Identifier を持ちます。</p>

<h4 id="devices-登録済みデバイス-iphoneipadなど"><strong>Devices: 登録済みデバイス (iPhone/iPadなど)</strong></h4>

<p>Development は実機で動作し、Distribution Ad Hoc の内測は登録されたデバイスのみ使用可能です。</p>

<blockquote>
  <p><strong><em>上限：100個；キャンセルを含め、毎年の支払いサイクルまでリリース枠はリセットされません。</em></strong></p>
</blockquote>

<h4 id="provisioning-profile以下profileプロビジョニングプロファイル"><strong>Provisioning Profile（以下、Profile）：プロビジョニングプロファイル</strong></h4>

<p>Certificates+Identifiers+Devices の関係のまとめ。</p>

<ul>
  <li>
    <p><strong>Development</strong> — 開発段階で使用するプロビジョニングプロファイルで、実機テストに必須です。プロファイルは Certificates、Identifiers、Devices の関係を含みます。</p>
  </li>
  <li>
    <p><strong>Ad Hoc</strong> — 内部テスト用にパッケージングされたプロビジョニングプロファイル（例：Firebase App Distributionへのデプロイ）で、プロファイルは Certificates、Identifiers、Devices の関係を含みます。</p>
  </li>
  <li>
    <p><strong>App Store</strong> — App Store / TestFlight にアップロードするためのパッケージに使用するプロビジョニングプロファイルで、プロファイルは Certificates と Identifiers の関係を含みます。</p>
  </li>
</ul>

<blockquote>
  <p><em>フォーマット：<code class="language-plaintext highlighter-rouge">.mobileprovision</code></em></p>
</blockquote>

<blockquote>
  <p><strong><em>注意：Profile はあくまで記述ファイルであり、関係性を示すもので、証明書自体は含みません。</em></strong></p>
</blockquote>

<h4 id="小結">小結</h4>

<p>総合すると、クリーンなマシンで Xcode の Apple アカウントにログインせずに実機ビルド（Development Certificate）やアーカイブビルド（Distribution Certificate）を行うには、<strong>2つのファイルが必要です</strong>：</p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">.mobileprovision</code> プロビジョニングプロファイル：証明書、識別子、デバイスの関係を記述。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">.p12</code> 証明書：証明書の実体（元の作成者のコンピュータからエクスポートされたもの）。</p>
  </li>
</ul>

<p><strong>また macOS 15以降の Keychain は以下に移動しました：</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>open /System/Library/CoreServices/Applications/Keychain<span class="se">\ </span>Access.app
</code></pre></div></div>

<p><em>ずっと探していた..</em></p>

<h4 id="よくあるエラー">よくあるエラー</h4>

<p><strong>⚠️⚠️⚠️ 証明書やプロファイルが正しいのにエラーが出る場合：</strong></p>

<blockquote>
  <p><em>ほとんどの場合、以前の証明書や複数の証明書が残っているため、Xcodeが混乱します。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>この問題はよく発生します！</em></strong></p>
</blockquote>

<ol>
  <li>
    <p>Xcode を閉じる</p>
  </li>
  <li>
    <p>macOS キーチェーンを開く: <code class="language-plaintext highlighter-rouge">open /System/Library/CoreServices/Applications/Keychain\ Access.app</code></p>
  </li>
  <li>
    <p>login キーチェーン -&gt; すべての項目 -&gt; 「apple development」を検索 -&gt; すべての証明書を削除</p>
  </li>
  <li>
    <p>Finder -&gt; 移動 -&gt; フォルダへ移動 -&gt; <code class="language-plaintext highlighter-rouge">~/Library/MobileDevice/Provisioning\ Profiles</code> -&gt; すべてのプロファイルを削除する</p>
  </li>
  <li>
    <p>証明書を再取得する</p>
  </li>
  <li>
    <p>Xcode を再起動すれば正常に動作するはずです。</p>
  </li>
</ol>

<p><strong>署名証明書 “iOS Distribution” が見つかりません / 署名証明書 “iOS Development” が見つかりません：</strong></p>

<pre><code class="language-vbnet">チームID "" に一致するプライベートキー付きの「iOS Distribution」署名証明書が見つかりませんでした。
チームID "" に一致するプライベートキー付きの「iOS Development」署名証明書が見つかりませんでした。
</code></pre>

<p><strong>理由:</strong></p>

<ul>
  <li>
    <p>iOS Distribution/iOS Development Certificate の証明書が不足しています</p>
  </li>
  <li>
    <p>iOS Distribution/iOS Development Certificate の証明書はあるが、対応するプライベートキーがありません</p>
  </li>
</ul>

<p><strong>解決方法:</strong></p>

<ul>
  <li>
    <p>Keychain 内のすべての古い Certificates 証明書と Profiles プロビジョニングプロファイルを削除する</p>
  </li>
  <li>
    <p>最初に Certificate を作成したコンピュータの Keychain で該当の証明書を見つけ、<code class="language-plaintext highlighter-rouge">.p12</code> 形式でエクスポートし、問題のあるコンピュータにインストールします。</p>
  </li>
  <li>
    <p><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Certificates, Identifiers &amp; Profiles</a> にアクセスし、古い証明書を取り消して再生成します。<br />
（ご安心ください。これはオンライン版のアプリには影響せず、開発およびビルド段階にのみ影響します）</p>
  </li>
</ul>

<p><strong>プロビジョニングプロファイル “” に署名証明書 “Apple Development: XXX” が含まれていません。 / プロビジョニングプロファイル “” に署名証明書 “Apple Distribution: XXX” が含まれていません。:</strong></p>

<p><strong>理由:</strong></p>

<ul>
  <li>現在選択されているプロビジョニングプロファイルは、現在の証明書と一致していません。</li>
</ul>

<p><strong>解決方法:</strong></p>

<ul>
  <li>
    <p>Keychain 内のすべての古い Certificates 証明書と Profiles プロビジョニングプロファイルを削除する</p>
  </li>
  <li>
    <p><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Certificates, Identifiers &amp; Profiles</a> で、プロビジョニングプロファイルが対応する証明書にチェックされているか、またはプロファイルを再生成して使用してください。</p>
  </li>
</ul>

<p><strong>チーム ‘’ に対応する ‘’ のプロファイルが見つかりませんでした: Xcode は ‘’ に一致するプロビジョニングプロファイルを見つけられませんでした。:</strong></p>

<p><strong>理由:</strong></p>

<ul>
  <li>指定された Provisioning profile が見つかりません。</li>
</ul>

<p><strong>解決方法:</strong></p>

<ul>
  <li>
    <p>Keychain 内のすべての古い Certificates 証明書と Profiles プロビジョニングプロファイルを削除する</p>
  </li>
  <li>
    <p><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Certificates, Identifiers &amp; Profiles</a> から該当するプロファイルをダウンロードして使用する</p>
  </li>
</ul>

<p><strong>プロビジョニングプロファイル “” のアプリID “” は、バンドルID “” と一致しません。 / プロビジョニングプロファイルがバンドル識別子と一致しません：</strong></p>

<p><strong>理由:</strong></p>

<ul>
  <li>Provisioning profile に現在の Bundle Identifier が含まれていません</li>
</ul>

<p><strong>解決方法:</strong></p>

<ul>
  <li>
    <p>Keychain 内のすべての古い Certificates 証明書と Profiles プロビジョニングプロファイルを削除する</p>
  </li>
  <li>
    <p><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Certificates, Identifiers &amp; Profiles</a> にアクセスし、IdentifiersでBundle Identifierが登録されていることを確認してください。</p>
  </li>
  <li>
    <p><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Certificates, Identifiers &amp; Profiles</a> で対応するプロファイルをダウンロードして使用します</p>
  </li>
</ul>

<p><strong>プロビジョニングプロファイル “” に現在選択されているデバイス “”（識別子 ）が含まれていません。:</strong></p>

<p><strong>理由:</strong></p>

<ul>
  <li>Provisioning profile に選択した実機の Device Identifier が含まれていません</li>
</ul>

<p><strong>解決方法:</strong></p>

<ul>
  <li>
    <p><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Certificates, Identifiers &amp; Profiles</a> の Devices で実機の識別子が登録されていることを確認する</p>
  </li>
  <li>
    <p><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Certificates, Identifiers &amp; Profiles</a> の Profiles に対応するプロファイルが実機で有効になっていることを確認してください。</p>
  </li>
  <li>
    <p>プロファイルの再ダウンロードに使用する</p>
  </li>
</ul>

<p><strong>別の開発／配布証明書を作成できません。利用可能な開発／配布証明書の最大数に達しました。 :</strong></p>

<p><strong>理由:</strong></p>

<p>作成済みの Development/Distribution 証明書が上限数に達しています。</p>

<p><strong>解決方法:</strong></p>

<ul>
  <li><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Certificates, Identifiers &amp; Profiles</a> にアクセスして、使っていない証明書を削除してください。</li>
</ul>

<p><strong>Xcodeの証明書は正しくて正常にビルドできるが、CLI（Fastlane）でビルドコマンドを実行すると署名エラーが発生する:</strong></p>

<p><strong>理由:</strong></p>

<p>ここでもう一つの落とし穴にハマりました。プロジェクトをうっかり iCloud の同期フォルダに置いてしまい、なぜか Fastlane がずっと証明書の問題を起こしていました（キー チェーンのアクセスに問題がある疑いです）。</p>

<p><strong>解決方法:</strong></p>

<p>iCloud 同期フォルダから移動するだけです。</p>

<h3 id="日常使用の問題シーン">日常使用の問題シーン</h3>

<h4 id="development-certificate-開発用証明書">Development Certificate (開発用証明書)</h4>

<p><img src="/assets/823ac523ccc8/1*uNICvLN0a9gdGAzi4EZ24g.webp" alt="" loading="lazy" decoding="async" width="1693" height="1029" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNjkzIiBoZWlnaHQ9IjEwMjkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/823ac523ccc8/1*uNICvLN0a9gdGAzi4EZ24g.png" /></p>

<ul>
  <li>
    <p>Match を導入して証明書を一元管理する前は、各開発者が自分の <code class="language-plaintext highlighter-rouge">Development Certificate</code> と <code class="language-plaintext highlighter-rouge">Development Profile</code> を作成していました。組織内に 1,000 人以上の開発者がいる場合、<a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Certificates, Identifiers &amp; Profiles, Devices</a> の管理画面は非常に混乱し、恐ろしい状態になります。</p>
  </li>
  <li>
    <p>もし外部の開発チームが開発のみを担当する場合でも、Apple Developer Program の管理画面にそのチームを追加し、彼ら自身の開発用証明書とプロファイルを作成させる必要があります。</p>
  </li>
</ul>

<h4 id="distribution-certificate-配布用証明書">Distribution Certificate (配布用証明書)</h4>

<p><img src="/assets/823ac523ccc8/1*1JKlvoO8d89dlcpz2mJvjg.webp" alt="" loading="lazy" decoding="async" width="1200" height="1105" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjExMDUiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/823ac523ccc8/1*1JKlvoO8d89dlcpz2mJvjg.png" /></p>

<ul>
  <li>
    <p>Distribution Certificate はチーム単位で作成されるため、各開発者プログラムのチームは作成できる配布証明書の数が限られています。</p>
  </li>
  <li>
    <p>一般的な方法としては、1人のエンジニアが Distribution Certificate を作成し、.p12 ファイルをエクスポートして、他のリリース担当の開発者や CI/CD マシンで使用します。</p>
  </li>
  <li>
    <p>チームが大きく、アプリの数が多いと、やり取りが非常に面倒になります。しかも <strong>毎年必ず更新が必要です</strong>。</p>
  </li>
  <li>
    <p><strong>Ad Hoc 配布時に新しいデバイスが登録されると、全員および CI/CD は新しいデバイスを有効にするためにプロファイルを再ダウンロードする必要があります。</strong></p>
  </li>
</ul>

<h3 id="fastlane-match"><a href="https://docs.fastlane.tools/actions/match/" target="_blank">Fastlane Match</a></h3>

<p>以上の問題を踏まえ、すべての証明書関連の管理を代行してくれるプラットフォームが欲しいと考えています。すべての開発者と CI/CD サービスはこのプラットフォームから統一してデータを取得・更新します。このプラットフォームのストレージは安全でなければなりません。それが — <a href="https://docs.fastlane.tools/actions/match/" target="_blank">Fastlane Match</a> です。</p>

<blockquote>
  <p><em>チーム全体で証明書とプロファイルを簡単に同期</em></p>
</blockquote>

<blockquote>
  <p><em>iOS と macOS のコード署名に新しいアプローチ：開発チーム全体で1つのコード署名IDを共有し、コード署名の設定を簡素化し、コード署名の問題を防ぎます。</em></p>
</blockquote>

<blockquote>
  <p><em>matchは<a href="https://codesigning.guide/" target="_blank">codesigning.guideのコンセプト</a>を実装したものです。matchは必要なすべての証明書とプロビジョニングプロファイルを作成し、それらを別のGitリポジトリ、Google Cloud、またはAmazon S3に保存します。選択したストレージにアクセスできるチームメンバーは、これらの認証情報をコード署名に使用できます。matchは壊れた証明書や期限切れの証明書も自動で修復します。チーム間で署名用の認証情報を共有する最も簡単な方法です</em></p>
</blockquote>

<p><img src="/assets/823ac523ccc8/1*UEL7Abx3PFrYbAc2yVlq8A.webp" alt="" loading="lazy" decoding="async" width="1883" height="777" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxODgzIiBoZWlnaHQ9Ijc3NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/823ac523ccc8/1*UEL7Abx3PFrYbAc2yVlq8A.png" /></p>

<p><strong>Fastlane Match：</strong></p>

<ul>
  <li>
    <p>App Store Connect と連携し（App Store Connect API または Apple Developer ログインセッションを通じて）、証明書を作成または更新します。</p>
  </li>
  <li>
    <p>証明書の成果物（<code class="language-plaintext highlighter-rouge">.mobileprovision</code> プロファイル、<code class="language-plaintext highlighter-rouge">.p12</code> 証明書、<code class="language-plaintext highlighter-rouge">.cer</code> 証明書）の3つのファイルを暗号化してGitリポジトリにアップロードします（他のストレージを使うことも可能です）。<br />
<code class="language-plaintext highlighter-rouge">.cer</code> 証明書は独立して保存します。これは証明書の有効性を確認するためです。</p>
  </li>
  <li>
    <p>権限を細かく分けたい場合は、2つのリポジトリに分けることができます。1つは Development 証明書を管理し、もう1つは Distribution 証明書を管理します。</p>
  </li>
</ul>

<p><a href="https://docs.fastlane.tools/actions/match/" target="_blank"><strong>フォルダ構成:</strong></a></p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">certs</code> フォルダには、すべての証明書とその秘密鍵が含まれています。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">profiles</code> フォルダには、すべてのプロビジョニングプロファイルが含まれています。</p>
  </li>
</ul>

<p><img src="/assets/823ac523ccc8/1*mStp0t3Ty3xGTKvbiBGtqw.webp" alt="&lt;https://docs.fastlane.tools/actions/match/&gt;" loading="lazy" decoding="async" width="683" height="508" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2ODMiIGhlaWdodD0iNTA4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/823ac523ccc8/1*mStp0t3Ty3xGTKvbiBGtqw.png" /></p>

<p><a href="https://docs.fastlane.tools/actions/match/" target="_blank">https://docs.fastlane.tools/actions/match/</a></p>

<p>暗号化アルゴリズム： <a href="https://github.com/fastlane/fastlane/blob/master/match/lib/match/encryption/encryption.rb" target="_blank">AES-256-GCM</a></p>

<p><strong>開発者、CI/CD サービス：</strong></p>

<ul>
  <li>
    <p>Fastlane match コマンドを使って証明書を一元管理する。</p>
  </li>
  <li>
    <p>Fastlane Match はまず Git リポジトリから証明書ファイルを取得し、復号して使用します。期限切れや使用不可の場合、Create/Write 権限があれば自動で再生成しリポジトリに Push します。Read 権限のみの場合はエラーを報告します。</p>
  </li>
</ul>

<p><strong>作成/書き込み：</strong></p>

<ul>
  <li>
    <p>証明書の管理を担当している人だけが、証明書の作成・更新およびPushアップロードを行うことができます。</p>
  </li>
  <li>
    <p><strong>重要な Distribution Certificate は独立したリポジトリに保管し、CI/CD サービスや管理者のみが使用できるようにするのが望ましい</strong></p>
  </li>
</ul>

<p><strong>読む:</strong></p>

<ul>
  <li>
    <p>他の開発者やCI/CDサービスは <strong>読み取り専用</strong> のPull証明書権限のみ持っています</p>
  </li>
  <li>
    <p>CI/CDサービスは、タスクを実行するたびに最新の証明書を取得します</p>
  </li>
  <li>
    <p>全員が同じDevelopment &amp; Distribution証明書を共有します</p>
  </li>
  <li>
    <p>人員異動後はMatch Repoの権限を失いますが、古い証明書をRevokeして再生成すれば、他のメンバーは再度Pullするだけで済みます（make projectスクリプトに統合していればさらに楽です）。</p>
  </li>
</ul>

<h3 id="fastlane-match-設定と使用方法">Fastlane Match 設定と使用方法</h3>

<p>Git Storage を例に、すべての証明書。</p>

<p><strong>1. 空の証明書保存用GitプライベートMatchリポジトリを作成する</strong><br />
すべてのCertificatesやProfilesは暗号化して保存されますが、そのリポジトリのアクセス権限はきちんと設定する必要があります。</p>

<ol>
  <li>ローカルで Git の SSH アクセス権限が設定されていることを確認します。<code class="language-plaintext highlighter-rouge">git clone git@github.com:xxx/certificates.git</code> を使用できます。</li>
</ol>

<blockquote>
  <p><em>ここでは <strong>SSH Git Clone Repo を統一して使用することを推奨します</strong>。なぜなら CI/CD でも同じ方法を使うからです。</em></p>
</blockquote>

<blockquote>
  <p><em>もし fastlane match の実行がずっと <code class="language-plaintext highlighter-rouge">If cloning the repo takes too long, you can use the </code>clone_branch_directly<code class="language-plaintext highlighter-rouge"> option in match.</code> で止まる場合、多くは SSH の権限設定の問題です。</em></p>
</blockquote>

<ol>
  <li>プロジェクトディレクトリで <code class="language-plaintext highlighter-rouge">bundle exec fastlane match init</code> を実行して設定を完了する</li>
</ol>

<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="mi">21</span><span class="p">:</span><span class="mi">54</span><span class="p">:</span><span class="mi">32</span><span class="p">]:</span> <span class="n">fastlane</span> <span class="n">match</span> <span class="err">は複数のストレージモードをサポートしています。使用したいものを選択してください</span><span class="p">:</span>
<span class="mi">1</span><span class="p">.</span> <span class="n">git</span>
<span class="mi">2</span><span class="p">.</span> <span class="n">google_cloud</span>
<span class="mi">3</span><span class="p">.</span> <span class="n">s3</span>
<span class="mi">4</span><span class="p">.</span> <span class="n">gitlab_secure_files</span>
<span class="o">#</span> <span class="n">git</span> <span class="err">を使う場合は</span> <span class="mi">1</span> <span class="err">を入力</span>
<span class="err">?</span>   <span class="mi">1</span>

<span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">04</span><span class="p">:</span><span class="mi">40</span><span class="p">]:</span> <span class="err">証明書とプロファイルを保存するための新しいプライベート</span> <span class="n">git</span> <span class="err">リポジトリを作成してください</span>
<span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">04</span><span class="p">:</span><span class="mi">40</span><span class="p">]:</span> <span class="n">Git</span> <span class="err">リポジトリの</span> <span class="n">URL</span><span class="p">:</span> <span class="n">git</span><span class="err">@</span><span class="n">github</span><span class="p">.</span><span class="n">com</span><span class="p">:</span><span class="n">xxx</span><span class="o">/</span><span class="n">certificates</span><span class="p">.</span><span class="n">git</span>
<span class="o">#</span> <span class="err">作成した</span> <span class="n">Git</span> <span class="err">プライベート</span> <span class="n">Match</span> <span class="err">リポジトリの</span> <span class="n">SSH</span> <span class="n">URL</span> <span class="err">を入力</span>

<span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">04</span><span class="p">:</span><span class="mi">47</span><span class="p">]:</span> <span class="s1">'./fastlane/Matchfile'</span> <span class="err">の作成に成功しました。コードエディタでファイルを開けます。</span>
<span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">04</span><span class="p">:</span><span class="mi">47</span><span class="p">]:</span> <span class="err">これで</span> <span class="err">`</span><span class="n">fastlane</span> <span class="n">match</span> <span class="n">development</span><span class="err">`、`</span><span class="n">fastlane</span> <span class="n">match</span> <span class="n">adhoc</span><span class="err">`、`</span><span class="n">fastlane</span> <span class="n">match</span> <span class="n">enterprise</span><span class="err">`、`</span><span class="n">fastlane</span> <span class="n">match</span> <span class="n">appstore</span><span class="err">`</span> <span class="err">を実行できます</span>
<span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">04</span><span class="p">:</span><span class="mi">47</span><span class="p">]:</span> <span class="err">各環境で初回実行時にプロビジョニングプロファイルと</span>
<span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">04</span><span class="p">:</span><span class="mi">47</span><span class="p">]:</span> <span class="err">証明書が作成されます。それ以降は既存のプロファイルを自動的にインポートします。</span>
<span class="p">[</span><span class="mi">22</span><span class="p">:</span><span class="mi">04</span><span class="p">:</span><span class="mi">47</span><span class="p">]:</span> <span class="err">詳細は</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">docs</span><span class="p">.</span><span class="n">fastlane</span><span class="p">.</span><span class="n">tools</span><span class="o">/</span><span class="n">actions</span><span class="o">/</span><span class="n">match</span><span class="o">/</span> <span class="err">をご覧ください</span>
</code></pre></div></div>

<ol>
  <li>完了すると <strong><code class="language-plaintext highlighter-rouge">fastlane/Matchfile</code> :</strong> が生成されます。</li>
</ol>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># あなたの Git プライベート Match リポジトリの SSH URL</span>
git_url<span class="o">(</span><span class="s2">"git@github.com:xxxx/certificates.git"</span><span class="o">)</span>

storage_mode<span class="o">(</span><span class="s2">"git"</span><span class="o">)</span>

<span class="nb">type</span><span class="o">(</span><span class="s2">"development"</span><span class="o">)</span> <span class="c"># デフォルトのタイプ、appstore、adhoc、enterprise、development が指定可能</span>

<span class="c"># app_identifier(["tools.fastlane.app", "tools.fastlane.app2"])</span>
<span class="c"># username("user@fastlane.tools") # あなたの Apple Developer Portal のユーザー名</span>

<span class="c"># 利用可能なオプションは `fastlane match --help` で確認できます</span>
<span class="c"># 他のオプションを有効にするには行頭の # を外してください</span>

<span class="c"># ドキュメントは https://docs.fastlane.tools/actions/match にあります</span>
</code></pre></div></div>

<p><strong>5. <a href="https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api" target="_blank">App Store Connect API .p8 Key</a> を作成し、APIキーを使って証明書を一元管理する:</strong></p>

<p><img src="/assets/823ac523ccc8/1*RFhS_XtZ3TfIJBAeoE-laA.webp" alt="" loading="lazy" decoding="async" width="1181" height="349" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTgxIiBoZWlnaHQ9IjM0OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/823ac523ccc8/1*RFhS_XtZ3TfIJBAeoE-laA.png" /></p>

<blockquote>
  <p><em>⚠️️️️ <a href="https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api" target="_blank"><strong>App Store Connect API .p8 キー</strong></a> <strong>の権限は非常に強力</strong> ため、証明書管理だけでなく、アプリのリリースや審査申請、バックエンドのユーザー管理やレビュー、財務レポートの管理も可能です。</em></p>
</blockquote>

<blockquote>
  <p><em>チームの .git に入れて全員がアクセスできるようにするかは、チームの状況に応じて決めてください。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>より高いリスク管理の方法は、管理者だけがアクセスでき、CI/CDで使用する際に暗号化して保存することです（本文後半で紹介します）。</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>ここではデモのために fastlane ディレクトリ内に直接配置しています。</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>また、本記事の Fastlane スクリプトは説明を簡単にするため、重複コードやプログラム構造は考慮していません。</em></strong></p>
</blockquote>

<h4 id="証明書管理">証明書管理</h4>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>platform :ios <span class="k">do
  </span>lane :match_development <span class="k">do</span> <span class="se">\\</span>|options<span class="se">\\</span>|
    <span class="c"># あなたのApp Identifier IDに変更してください</span>
    app_identifier <span class="o">=</span> <span class="s2">"li.zhgchg.myApp"</span>

    <span class="nb">type</span> <span class="o">=</span> options.fetch<span class="o">(</span>:type, <span class="s2">"development"</span><span class="o">)</span>
    isRead <span class="o">=</span> options.fetch<span class="o">(</span>:isRead, <span class="nb">true</span><span class="o">)</span>
    <span class="k">if </span>isRead 
      <span class="nb">readonly</span> <span class="o">=</span> <span class="nb">true
      </span>force <span class="o">=</span> <span class="nb">false
    </span><span class="k">else
      </span><span class="nb">readonly</span> <span class="o">=</span> <span class="nb">false
      </span>force <span class="o">=</span> <span class="nb">true</span>

      <span class="c"># App Store Connect APIキーが必要で、Appleの管理画面で証明書を操作する権限があります</span>
      <span class="c"># App Store Connect APIの.p8キーが ./fastlane/ ディレクトリにあると仮定します</span>
      app_store_connect_api_key<span class="o">(</span>
        key_id: <span class="s2">"XXXXXX"</span>,
        issuer_id: <span class="s2">"XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX"</span>,
        key_filepath: <span class="s2">"./fastlane/AuthKey_XXXXXX.p8"</span>,
      <span class="o">)</span>
    end

    <span class="c"># app_identifierのDevelopment証明書を取得</span>
    match<span class="o">(</span>
      <span class="nb">type</span>: <span class="nb">type</span>,
      app_identifier: app_identifier, 
      <span class="nb">readonly</span>: <span class="nb">readonly</span>, <span class="c"># 必要に応じてcert/profileを更新・アップロードできるかどうか</span>
      force: force <span class="c"># 無条件にプロビジョニングプロファイルを再作成するかどうか</span>
    <span class="o">)</span>
  end
end
</code></pre></div></div>

<p><strong>Development Certificate と Profile を作成し、Match リポジトリにアップロードする:</strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle exec fastlane match_development type:development isRead:false
[22:22:38]: 'li.zhgchg.myApp' のために 'match Development li.zhgchg.myApp' という名前の新しいプロビジョニングプロファイルを 'ios' プラットフォーム用に作成しています
[22:22:39]: プロビジョニングプロファイルをダウンロード中...
[22:22:39]: プロビジョニングプロファイルのダウンロードに成功しました...
[22:22:39]: プロビジョニングプロファイルをインストール中...
/var/folders/pk/978f3gws7ml0bkmrw245cg_c0000gn/T/d20260103-5010-v6r6w2/profiles/development/Development_li.zhgchg.myApp.mobileprovision
[22:22:39]: プロビジョニングプロファイルをインストール中...
[22:22:39]: 🔒 証明書リポジトリの暗号化に成功しました
[22:22:39]: リモートGitリポジトリへ変更をプッシュしています...
[22:22:42]: Gitリポジトリへのファイルアップロードが完了しました [git@github.com:xxxx/certificates.git]
</code></pre></div></div>

<ul>
  <li>エラーがなければ、Development Certificate と Profile の生成、インストールが成功し、Match リポジトリへの同期プッシュも成功したことを意味します。</li>
</ul>

<p><strong>初回作成時に <code class="language-plaintext highlighter-rouge">Passphrase</code> の設定が必要です：</strong></p>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="ss">23:29:12</span><span class="p">]:</span> <span class="sx">証明書を暗号化/復号化するために使用するパスフレーズを入力してください</span>
<span class="p">[</span><span class="ss">23:29:12</span><span class="p">]:</span> <span class="sx">このパスフレーズはリポジトリごとに固有で、ローカルキーチェーンに保存されます</span>
<span class="p">[</span><span class="ss">23:29:12</span><span class="p">]:</span> <span class="sx">別のマシンで</span> match を実行する際に必要になるため、パスワードを忘れないようにしてください
<span class="p">[</span><span class="ss">23:29:12</span><span class="p">]:</span> <span class="sx">Match</span> ストレージのパスフレーズ:
</code></pre></div></div>

<ul>
  <li>
    <p>この値は、あなたのすべての Match リポジトリ上のファイルを暗号化する際に必要となる参照（パスフレーズ + ランダムソルト）です。</p>
  </li>
  <li>
    <p>ランダムな文字列を生成し、設定して記録することをおすすめします。<a href="https://www.random.org/strings/?num=1&amp;len=32&amp;digits=on&amp;upperalpha=on&amp;loweralpha=on&amp;unique=on&amp;format=html&amp;rnd=new" target="_blank">隨機字串</a></p>
  </li>
  <li>
    <p>将来の更新や他の人が Match リポの証明書を取得する際には、この文字列を入力して元のファイルを復号化する必要があります。</p>
  </li>
</ul>

<p><strong>チームの他のメンバーは Match リポジトリから Development Certificate と Profile を一括で Pull する:</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle <span class="nb">exec </span>fastlane match_development <span class="nb">type</span>:development
</code></pre></div></div>

<p>（コード部分のため翻訳不要）</p>

<p><strong>初めて使用する際にログインキーチェーンのパスワードを尋ねられます。これは証明書をキーチェーンにインストールするためで、2回入力して確認してください:</strong></p>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="ss">16:52:59</span><span class="p">]:</span> <span class="sx">証明書をインストールしています...</span>
<span class="p">[</span><span class="ss">16:53:00</span><span class="p">]:</span> <span class="sx">ローカルのコード署名IDが見つかりません。</span>
security find-identity -v -p codesigning を実行するとこの出力が得られます。
このStack Overflowのスレッドに詳細があります：https://stackoverflow.com/q/35390072/774。
（Keychain Accessで期限切れのWWDR証明書を確認してください：https://stackoverflow.com/a/35409835/774 に詳細があります。）
<span class="p">[</span><span class="ss">16:53:00</span><span class="p">]:</span> <span class="sx">/Users/zhgchgli/Library/Keychains/login.keychain-db</span> のパスワードを入力してください
<span class="p">[</span><span class="ss">16:53:00</span><span class="p">]:</span> <span class="sx">このパスフレーズは</span> fastlane_keychain_login という名前でローカルキーチェーンに保存され、今後の実行で使用されます
<span class="p">[</span><span class="ss">16:53:00</span><span class="p">]:</span> <span class="sx">このプロンプトは</span> <span class="nn">'keychain_password'</span> オプションまたは 'MATCH_KEYCHAIN_PASSWORD' 環境変数を指定することで回避できます
<span class="p">[</span><span class="ss">16:53:00</span><span class="p">]:</span> <span class="sx">ログインキーチェーンのパスワード：********</span>
<span class="p">[</span><span class="ss">16:53:24</span><span class="p">]:</span> <span class="sx">ログインキーチェーンのパスワードをもう一度入力してください：********</span>
</code></pre></div></div>

<p><strong>もし Match Development で証明書を取得した後も、Xcode がエラーや無効と表示し続ける場合:</strong></p>

<p>前述のよくあるエラーを参考にすると、多くの場合は古い不要な証明書が原因です。すべての証明書を削除してから再度取得すれば解決するはずです。</p>

<p>—</p>

<p><strong>AdHoc Distribution Certificate と Profile の作成および Match リポジトリへのアップロード：</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle <span class="nb">exec </span>fastlane match_development <span class="nb">type</span>:adhoc isRead:false
</code></pre></div></div>

<p>（コード内のコメントはありませんので、そのまま保持しています。）</p>

<p><strong>AppStore Distribution 証明書とプロファイルの作成および Match リポジトリへのアップロード:</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle <span class="nb">exec </span>fastlane match_development <span class="nb">type</span>:appstore isRead:false
</code></pre></div></div>

<p><strong>CI/CD サービスは統一して Match リポジトリから Distribution Certificate と Profile (<code class="language-plaintext highlighter-rouge">isRead:true</code>) をプルし、その後ビルドと配布タスクを実行します。</strong></p>

<h4 id="新しいデバイスの登録">新しいデバイスの登録</h4>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">platform</span> <span class="o">:</span><span class="n">ios</span> <span class="k">do</span>  
  <span class="n">desc</span> <span class="s2">"新しいデバイスを登録し、プロファイルを更新する"</span>
  <span class="n">lane</span> <span class="o">:</span><span class="n">registerDevice</span> <span class="k">do</span> <span class="err">\\</span><span class="o">|</span><span class="n">options</span><span class="err">\\</span><span class="o">|</span>
    <span class="c1"># あなたの App Identifier ID に変更してください</span>
    <span class="n">app_identifier</span> <span class="o">=</span> <span class="s2">"li.zhgchg.myApp"</span>

    <span class="c1"># Appleの管理画面で証明書を操作するにはApp Store Connect APIキーが必要です</span>
    <span class="c1"># ここでは App Store Connect API の .p8 キーが ./fastlane/ ディレクトリにあると仮定します</span>
    <span class="nf">app_store_connect_api_key</span><span class="p">(</span>
      <span class="n">key_id</span><span class="o">:</span> <span class="s2">"XXXXXX"</span><span class="p">,</span>
      <span class="n">issuer_id</span><span class="o">:</span> <span class="s2">"XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX"</span><span class="p">,</span>
      <span class="n">key_filepath</span><span class="o">:</span> <span class="s2">"./fastlane/AuthKey_XXXXXX.p8"</span><span class="p">,</span>
    <span class="p">)</span>
    <span class="c1"># 入力: UDID とデバイス名</span>
    <span class="n">udid</span> <span class="o">=</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">udid</span><span class="p">]</span> <span class="err">\\</span><span class="o">|</span><span class="err">\\</span><span class="o">|</span> <span class="no">UI</span><span class="mf">.</span><span class="nf">input</span><span class="p">(</span><span class="s2">"デバイスのUDIDを入力してください:"</span><span class="p">)</span>
    <span class="n">device_name</span> <span class="o">=</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">name</span><span class="p">]</span> <span class="err">\\</span><span class="o">|</span><span class="err">\\</span><span class="o">|</span> <span class="no">UI</span><span class="mf">.</span><span class="nf">input</span><span class="p">(</span><span class="s2">"デバイス名を入力してください:"</span><span class="p">)</span>
    <span class="no">UI</span><span class="mf">.</span><span class="nf">message</span><span class="p">(</span><span class="s2">"📱 デバイスを登録中 #</span><span class="si">{</span><span class="nv">device_name</span><span class="si">}</span><span class="s2"> (#</span><span class="si">{</span><span class="nv">udid</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
    <span class="nf">register_device</span><span class="p">(</span>
      <span class="n">name</span><span class="o">:</span> <span class="n">device_name</span><span class="p">,</span>
      <span class="n">udid</span><span class="o">:</span> <span class="n">udid</span><span class="p">,</span>
      <span class="n">platform</span><span class="o">:</span> <span class="s1">'ios'</span>
    <span class="p">)</span>

    <span class="c1"># app_identifier の Development 証明書を更新</span>
    <span class="k">match</span><span class="p">(</span>
      <span class="n">type</span><span class="o">:</span> <span class="s2">"development"</span><span class="p">,</span>
      <span class="n">app_identifier</span><span class="o">:</span> <span class="n">app_identifier</span><span class="p">,</span> 
      <span class="k">readonly</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="c1"># 必要に応じて証明書・プロファイルを更新・アップロード</span>
      <span class="n">force_for_new_devices</span><span class="o">:</span> <span class="kc">true</span> <span class="c1"># 新しいデバイスの場合はプロビジョニングプロファイルを再作成</span>
    <span class="p">)</span>

    <span class="c1"># app_identifier の AdHoc 証明書を更新</span>
    <span class="k">match</span><span class="p">(</span>
      <span class="n">type</span><span class="o">:</span> <span class="s2">"adhoc"</span><span class="p">,</span>
      <span class="n">app_identifier</span><span class="o">:</span> <span class="n">app_identifier</span><span class="p">,</span> 
      <span class="k">readonly</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="c1"># 必要に応じて証明書・プロファイルを更新・アップロード</span>
      <span class="n">force_for_new_devices</span><span class="o">:</span> <span class="kc">true</span> <span class="c1"># 新しいデバイスの場合はプロビジョニングプロファイルを再作成</span>
    <span class="p">)</span>
  <span class="n">end</span>
<span class="n">end</span>
</code></pre></div></div>

<p>登録が完了した後、他の開発者や CI/CD サービスが Match リポジトリから Profile（Development または AdHoc）を取得すると、新しいデバイスが含まれます。</p>

<h3 id="fastlane-match-x-cicd-ワークフロー統合">Fastlane Match x CI/CD ワークフロー統合</h3>

<p>Fastlane MatchでPush／Pullの証明書を生成・取得する方法を大まかに説明した後は、次にそれをCI/CDプロセスに統合する方法について説明します。</p>

<h4 id="問題1--private-match-リポジトリのクローン方法">問題1 — Private Match リポジトリのクローン方法</h4>

<p>最もよくある問題の一つは、CI/CDでプライベートなMatchリポジトリをどうやってCloneするかです。ローカル開発では、統一してsshでgit cloneを使い、自分のアカウントのsshキーを使っているため問題ありません。しかし、CI/CDにはこのキーがなく、個人のキーを使うこともできますが、安全とは言えません。</p>

<p><strong>GitHub — リポジトリデプロイキー:</strong></p>

<ol>
  <li>
    <p>まずローカルでプライベートキーとパブリックキーを生成します: <code class="language-plaintext highlighter-rouge">ssh-keygen -t rsa -b 4096 -f ./id_rsa</code> ( <strong>パスフレーズは入力しないでください</strong> )</p>
  </li>
  <li>
    <p><strong>Match Private Repo</strong> -&gt; Settings -&gt; Security -&gt; Deploy keys -&gt; Add deploy key に移動します:</p>
  </li>
</ol>

<p><img src="/assets/823ac523ccc8/1*nzo-oPRi7DDxPvtJIWBspw.webp" alt="" loading="lazy" decoding="async" width="1149" height="774" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQ5IiBoZWlnaHQ9Ijc3NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/823ac523ccc8/1*nzo-oPRi7DDxPvtJIWBspw.png" /></p>

<ol>
  <li>テキストエディタで「 <code class="language-plaintext highlighter-rouge">id_rsa.pub</code> 」を開き、内容をコピーして Key -&gt;「Add key」に貼り付けます</li>
</ol>

<p><img src="/assets/823ac523ccc8/1*mbwtijzM-2iAzfgFiT32rw.webp" alt="" loading="lazy" decoding="async" width="1496" height="780" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDk2IiBoZWlnaHQ9Ijc4MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/823ac523ccc8/1*mbwtijzM-2iAzfgFiT32rw.png" /></p>

<ol>
  <li>メインのリポジトリに戻り、Settings -&gt; Security -&gt; Secrets and variables に移動します。</li>
</ol>

<p><img src="/assets/823ac523ccc8/1*jvY8Yg6tI85LNKHgIaHVVQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="869" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/823ac523ccc8/1*jvY8Yg6tI85LNKHgIaHVVQ.png" /></p>

<ol>
  <li>SSHプライベートキーの内容をSecretに追加:</li>
</ol>

<p><img src="/assets/823ac523ccc8/1*8WiPfOz21rJWD6yiMwP3aw.webp" alt="" loading="lazy" decoding="async" width="1200" height="689" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY4OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/823ac523ccc8/1*8WiPfOz21rJWD6yiMwP3aw.png" /></p>

<ul>
  <li>名前: <code class="language-plaintext highlighter-rouge">MATCH_REPO_DEPLOY_PRIVATE_KEY</code></li>
</ul>

<ol>
  <li>メインリポジトリの GitHub Actions に SSH キーを設定する:</li>
</ol>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">CI - デプロイ</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="na">push</span><span class="pi">:</span>
    <span class="na">branches</span><span class="pi">:</span> <span class="pi">[</span> <span class="nv">main</span> <span class="pi">]</span>
  <span class="na">pull_request</span><span class="pi">:</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">build</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">現在のリポジトリをチェックアウト (リポジトリA)</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">デプロイキーのためのSSH設定</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">mkdir -p ~/.ssh</span>
          <span class="s">echo "${{ secrets.MATCH_REPO_DEPLOY_PRIVATE_KEY }}" &gt; ~/.ssh/id_ed25519</span>
          <span class="s">chmod 600 ~/.ssh/id_ed25519</span>
          <span class="s">ssh-keyscan github.com &gt;&gt; ~/.ssh/known_hosts</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">クローンのテスト</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">git clone git@github.com:xxxx/match-certificates.git</span>
<span class="c1"># 成功！</span>
<span class="c1"># .. デプロイジョブを実行...</span>
</code></pre></div></div>

<ol>
  <li>設定成功！</li>
</ol>

<h4 id="問題2-app-store-connect-api-p8-キーの安全な保管と使用">問題2— App Store Connect API .p8 キーの安全な保管と使用</h4>

<p>GitHub Actions はファイルを直接保存できないため、まず文字列として保存し、その後ファイルに書き込みます。</p>

<ol>
  <li>
    <p>同じ問題のステップ1と同様に、メインのリポジトリに <code class="language-plaintext highlighter-rouge">APP_STORE_CONNECT_API_KEY_CONTENT</code> シークレットを追加します。</p>
  </li>
  <li>
    <p>テキストエディタで <code class="language-plaintext highlighter-rouge">AuthKey_XXXXXX.p8</code> を開き、内容をコピーして貼り付けてください。</p>
  </li>
  <li>
    <p><strong>メインリポジトリの GitHub Actions に内容を読み取りファイルに書き込むステップを追加：</strong></p>
  </li>
</ol>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">CI - Deploy</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="na">push</span><span class="pi">:</span>
    <span class="na">branches</span><span class="pi">:</span> <span class="pi">[</span> <span class="nv">main</span> <span class="pi">]</span>
  <span class="na">pull_request</span><span class="pi">:</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">build</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">現在のリポジトリをチェックアウト (Repo A)</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">デプロイキー用のSSH設定</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">mkdir -p ~/.ssh</span>
          <span class="s">echo "${{ secrets.MATCH_REPO_DEPLOY_PRIVATE_KEY }}" &gt; ~/.ssh/id_ed25519</span>
          <span class="s">chmod 600 ~/.ssh/id_ed25519</span>
          <span class="s">ssh-keyscan github.com &gt;&gt; ~/.ssh/known_hosts</span>  
      
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">シークレットキーをファイルに書き込む</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">APP_STORE_CONNECT_API_KEY_CONTENT</span><span class="pi">:</span> <span class="s">${{ secrets.APP_STORE_CONNECT_API_KEY_CONTENT }}</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s"># fastlaneディレクトリが存在することを確認</span>
          <span class="s">mkdir -p ./fastlane</span>
      
          <span class="s"># ファイルパスを作成</span>
          <span class="s">APP_STORE_CONNECT_API_KEY_PATH=./fastlane/AuthKey_XXXXXX.p8</span>
      
          <span class="s"># 内容を書き込む（改行を保持）</span>
          <span class="s">echo "$APP_STORE_CONNECT_API_KEY_CONTENT" &gt; "$APP_STORE_CONNECT_API_KEY_PATH"</span>
      
          <span class="s"># （任意）パーミッションを制限</span>
          <span class="s">chmod 600 "$APP_STORE_CONNECT_API_KEY_PATH"</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Firebaseへデプロイ</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">MATCH_PASSWORD</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">secrets.MATCH_PASSWORD</span><span class="nv"> </span><span class="s">}}"</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">bundle exec fastlane deploy_to_firebase</span>
</code></pre></div></div>

<h4 id="問題3--private-match-repo-の-passphrase-を設定しmatch-時のプロンプト中断を防ぐ">問題3 — Private Match Repo の Passphrase を設定し、Match 時のプロンプト中断を防ぐ</h4>

<ol>
  <li>
    <p>同じ手順1で、メインリポジトリに <code class="language-plaintext highlighter-rouge">MATCH_PASSWORD</code> を Secret として追加してください。</p>
  </li>
  <li>
    <p>Fastlane Match リポジトリに設定した <code class="language-plaintext highlighter-rouge">Passphrase</code> を入力してください</p>
  </li>
  <li>
    <p><strong>メインリポジトリの GitHub Actions に</strong> <code class="language-plaintext highlighter-rouge">env: secret.MATCH_PASSWORD</code> <strong>を追加：</strong></p>
  </li>
</ol>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">CI - Deploy</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="na">push</span><span class="pi">:</span>
    <span class="na">branches</span><span class="pi">:</span> <span class="pi">[</span> <span class="nv">main</span> <span class="pi">]</span>
  <span class="na">pull_request</span><span class="pi">:</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">build</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">現在のリポジトリをチェックアウト (Repo A)</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">デプロイキー用のSSH設定</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">mkdir -p ~/.ssh</span>
          <span class="s">echo "${{ secrets.MATCH_REPO_DEPLOY_PRIVATE_KEY }}" &gt; ~/.ssh/id_ed25519</span>
          <span class="s">chmod 600 ~/.ssh/id_ed25519</span>
          <span class="s">ssh-keyscan github.com &gt;&gt; ~/.ssh/known_hosts</span>  
      
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">シークレットキーをファイルに書き込む</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">APP_STORE_CONNECT_API_KEY_CONTENT</span><span class="pi">:</span> <span class="s">${{ secrets.APP_STORE_CONNECT_API_KEY_CONTENT }}</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s"># fastlaneディレクトリが存在することを確認</span>
          <span class="s">mkdir -p ./fastlane</span>
      
          <span class="s"># ファイルパスを作成</span>
          <span class="s">APP_STORE_CONNECT_API_KEY_PATH=./fastlane/AuthKey_XXXXXX.p8</span>
      
          <span class="s"># 内容を書き込む（改行を保持）</span>
          <span class="s">echo "$APP_STORE_CONNECT_API_KEY_CONTENT" &gt; "$APP_STORE_CONNECT_API_KEY_PATH"</span>
      
          <span class="s"># （任意）パーミッションを制限</span>
          <span class="s">chmod 600 "$APP_STORE_CONNECT_API_KEY_PATH"</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Firebaseへデプロイ</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">MATCH_PASSWORD</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">secrets.MATCH_PASSWORD</span><span class="nv"> </span><span class="s">}}"</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">bundle exec fastlane deploy_to_firebase</span>
</code></pre></div></div>

<h4 id="問題4--self-hosted-runner-上の-keychain-処理">問題4 — Self-hosted Runner 上の Keychain 処理</h4>

<p>クラウドマシンは毎回クリーンで全く新しい環境ですが、Self-hosted Runner を使う場合、Fastlane で <code class="language-plaintext highlighter-rouge">derived_data_path</code>、<code class="language-plaintext highlighter-rouge">output_directory</code>、<code class="language-plaintext highlighter-rouge">buildlog_path</code>、<code class="language-plaintext highlighter-rouge">reinstall_app</code> を指定して、毎回実行環境をクリーンにできます。しかし、Certificates や Profiles はシステムの Keychain にインストールされるため、これをどう扱うべきでしょうか？</p>

<p>実は Fastlane は私たちのために、Match の前にクリーンな Keychain を作成することも考慮しています：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">CI - デプロイ</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="na">push</span><span class="pi">:</span>
    <span class="na">branches</span><span class="pi">:</span> <span class="pi">[</span> <span class="nv">main</span> <span class="pi">]</span>
  <span class="na">pull_request</span><span class="pi">:</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">build</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">現在のリポジトリをチェックアウト (Repo A)</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">デプロイキー用のSSH設定</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">mkdir -p ~/.ssh</span>
          <span class="s">echo "${{ secrets.MATCH_REPO_DEPLOY_PRIVATE_KEY }}" &gt; ~/.ssh/id_ed25519</span>
          <span class="s">chmod 600 ~/.ssh/id_ed25519</span>
          <span class="s">ssh-keyscan github.com &gt;&gt; ~/.ssh/known_hosts</span>  
      
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">シークレットキーをファイルに書き込み</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">APP_STORE_CONNECT_API_KEY_CONTENT</span><span class="pi">:</span> <span class="s">${{ secrets.APP_STORE_CONNECT_API_KEY_CONTENT }}</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s"># fastlaneディレクトリが存在することを確認</span>
          <span class="s">mkdir -p ./fastlane</span>
      
          <span class="s"># ファイルパスを作成</span>
          <span class="s">APP_STORE_CONNECT_API_KEY_PATH=./fastlane/AuthKey_XXXXXX.p8</span>
      
          <span class="s"># 内容を書き込み（改行を保持）</span>
          <span class="s">echo "$APP_STORE_CONNECT_API_KEY_CONTENT" &gt; "$APP_STORE_CONNECT_API_KEY_PATH"</span>
      
          <span class="s"># （任意）パーミッションを制限</span>
          <span class="s">chmod 600 "$APP_STORE_CONNECT_API_KEY_PATH"</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">fastlaneキーチェーンを作成</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">KEYCHAIN_NAME</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">runner.name</span><span class="nv"> </span><span class="s">}}"</span>
          <span class="na">MATCH_PASSWORD</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">secrets.MATCH_PASSWORD</span><span class="nv"> </span><span class="s">}}"</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">bundle exec fastlane run create_keychain \</span>
            <span class="s">name:"$KEYCHAIN_NAME" \</span>
            <span class="s">password:"$MATCH_PASSWORD" \</span>
            <span class="s">unlock:true \</span>
            <span class="s">timeout:0 \</span>
            <span class="s">lock_when_sleeps:false</span>
      
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Firebaseへデプロイ</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">MATCH_PASSWORD</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">secrets.MATCH_PASSWORD</span><span class="nv"> </span><span class="s">}}"</span>
          <span class="na">KEYCHAIN_NAME</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">runner.name</span><span class="nv"> </span><span class="s">}}"</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">bundle exec fastlane deploy_to_firebase</span>

      <span class="c1"># 🔥 成功・失敗に関わらず必ず実行</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">fastlaneキーチェーンを削除</span>
        <span class="na">if</span><span class="pi">:</span> <span class="s">always()</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">KEYCHAIN_NAME</span><span class="pi">:</span> <span class="s">${{ runner.name }}</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">bundle exec fastlane run delete_keychain \</span>
            <span class="s">name:"$KEYCHAIN_NAME"</span>
</code></pre></div></div>

<ul>
  <li>
    <p>各Runnerは同時に1つだけ実行されるため、Runner NameをKeychain Nameとして使用し、各Runnerはそれぞれ独自のKeychainを持ちます。</p>
  </li>
  <li>
    <p>実行完了後、成功・失敗に関わらず削除されます。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">keychain_password</code> は特に別途設定せず、統一して <code class="language-plaintext highlighter-rouge">MATCH_PASSWORD</code> を使用しました。</p>
  </li>
</ul>

<p><code class="language-plaintext highlighter-rouge">Fastlane/Fastfile</code> の match メソッドに keychain パラメータを追加する:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#...</span>
    <span class="n">match</span><span class="p">(</span>
      <span class="ss">type: </span><span class="s2">"adhoc"</span><span class="p">,</span>
      <span class="ss">app_identifier: </span><span class="n">app_identifier</span><span class="p">,</span> 
      <span class="ss">readonly: </span><span class="kp">false</span><span class="p">,</span> <span class="c1"># 必要に応じて cert / profile を更新・アップロードする</span>
      <span class="ss">force_for_new_devices: </span><span class="kp">true</span><span class="p">,</span> <span class="c1"># 新しいデバイスがある場合、プロビジョニングプロファイルを再作成する</span>
      <span class="ss">keychain_name: </span><span class="no">ENV</span><span class="p">[</span><span class="s1">'KEYCHAIN_NAME'</span><span class="p">],</span> <span class="c1"># デフォルト値: nil</span>
      <span class="ss">keychain_password: </span><span class="no">ENV</span><span class="p">[</span><span class="s1">'MATCH_PASSWORD'</span><span class="p">]</span> <span class="c1"># デフォルト値: nil</span>
    <span class="p">)</span>
<span class="c1">#...</span>
</code></pre></div></div>

<p>こうすることで、Match が証明書を取得するときに共用の login キーチェーンではなく、指定したキーチェーンに保存されます。</p>

<h3 id="結語">結語</h3>

<p>Fastlane の範囲は非常に広いため、ここでは Fastlane Match の使用手順のみを記録します。Fastlane を使ったテスト実行やビルド・リリースなどの他の Lane については、機会があれば別の記事で補足します。Match に関する他の問題や事例があれば、また追記しますので、コメントでの質問も歓迎します！</p>

<h3 id="関連記事">関連記事</h3>

<ul>
  <li>
    <p><a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/">CI/CD 実践ガイド（1）：CI/CD とは？CI/CD を使って安定かつ効率的な開発チームを作るには？ツールの選び方は？</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/">CI/CD 実践ガイド（二）：GitHub Actions と self-hosted Runner の使用と構築大全</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/">CI/CD 実践ガイド（三）：GitHub Actions を使ったアプリプロジェクトの CI と CD ワークフローの実装</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/">CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</a></p>
  </li>
</ul>

<p><strong>ぜひご覧ください。🤞🏻</strong></p>

<p><em><a href="https://medium.com/zrealm-ios-dev/ios-certificates-identifiers-profiles-%E6%98%AF%E4%BB%80%E9%BA%BC%E5%8F%8A-fastlane-match-%E7%B5%B1%E4%B8%80%E7%AE%A1%E7%90%86%E6%86%91%E8%AD%89%E8%88%87-ci-cd-%E7%9A%84%E4%B8%80%E4%BA%9B%E7%AD%86%E8%A8%98-823ac523ccc8" target="_blank">Post</a> Medium から <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a> によって変換されました。</em></p>]]></content>
  </entry><entry>
    <title type="html">Medium API｜GraphQLデータスクレイピングとCloudflare突破技術の実践ガイド</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/medium-api-graphql%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0%E3%81%A8cloudflare%E7%AA%81%E7%A0%B4%E6%8A%80%E8%A1%93%E3%81%AE%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-88f0fb935120/" rel="alternate" type="text/html" title="Medium API｜GraphQLデータスクレイピングとCloudflare突破技術の実践ガイド" />
    <published>2025-12-31T12:36:53+08:00</published>
    <updated>2026-01-02T22:43:48+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/88f0fb935120</id><summary type="html">MediumのGraphQL Private APIを活用し、記事データを安全にスクレイピング。Cloudflareの認証障壁を突破する具体的手法を解説し、効率的な記事バックアップを実現します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="クラウドフレア" /><category term="ミディアム" /><category term="api" /><category term="graphql" /><category term="ミディアムapi" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/88f0fb935120/1*Lh9a_XR4zvvsaP3y58x9Aw.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/medium-api-graphql%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0%E3%81%A8cloudflare%E7%AA%81%E7%A0%B4%E6%8A%80%E8%A1%93%E3%81%AE%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-88f0fb935120/"><![CDATA[<h3 id="medium-api-データスクレイピングと-cloudflare-攻防の心境の変化">Medium API データスクレイピングと Cloudflare 攻防の心境の変化</h3>

<p>Medium Graphql Private API を使ったデータ取得、記事バックアップ、Cloudflare 認証ブロック突破方法。</p>

<h4 id="背景">背景</h4>

<p>2018年からMediumで記事を書き始め、2022年頃には記事数が50本以上、約6万字と約3GBの画像を蓄積しました（2025年までに120本以上/10万字以上/6GB以上の画像に達しています）。<strong>バックアップはありません！バックアップはありません！バックアップはありません！</strong> ずっとMediumのエディターを直接使って記事を書いているので（エディターは本当に使いやすいです）、<strong>書き終えたらすぐに保存して公開し、ローカルには一切バックアップを取っていません。</strong></p>

<p>あの時、不安な気持ちが自然と湧いてきました。もしある日 Medium がなくなったら、私の記事も消えてしまうのでは？（しかもその数年間、Medium の状況はずっと良くなく、収益も出ていませんでした）あるいは、アカウントが突然停止されたら、これまでの努力がすべて無駄になってしまうのでは？</p>

<p>そこでその年から Medium のデータ、特に記事内容の取得とダウンロードによるバックアップ方法の研究を始めました。</p>

<h4 id="medium-html-">Medium HTML ❌</h4>

<p>構造が非常に複雑で変わりやすく、クロールが遅いため、ブラウザを直接使って内容を取得するのは最悪の方法です。</p>

<h4 id="medium公式api-">Medium公式API ❌</h4>

<p><a href="https://github.com/Medium/medium-api-docs" target="_blank"><img src="https://opengraph.githubassets.com/e5dab4a39df5809789f4fa59924d1eda04c658aa27cd430b543a80ff7f74a935/Medium/medium-api-docs" alt="" /></a></p>

<blockquote>
  <p><strong><em>警告 MediumのAPIはもはやサポートされていません。使用は推奨しません。</em></strong></p>
</blockquote>

<p>Medium はかつて公式の API を提供していましたが、おそらくリリースから間もなく停止されました。これは製品の目的と異なるためだと推測されます。Medium は自社内でのトラフィックを重視しており、外部が API を通じてデータを取得できるようにすることを避けているようです。</p>

<h4 id="medium-非公式api-">Medium 非公式API 🤔</h4>

<p><a href="https://mediumapi.com/" target="_blank"><img src="https://mediumapi.com/imgs/mediumapi-website-image.jpg" alt="" /></a></p>

<p>また公式がAPIを提供していないため、個人の開発者が外部向けのAPIを作成し、必要なユーザーが接続できるようにしています。しかし、その仕組みもMediumのPrivate APIを利用していると推測されます。単にその一層のラッピングを越えて、リクエストをPrivate APIに変換し、元のデータを取得しているだけです。</p>

<blockquote>
  <p><strong><em>料金も安くなく、約2,500回のリクエストで5米ドル</em></strong> <em>；このサービスはかなり長く続いていますが、結局はMedium Private APIを使うので、自分で解析して自分でリクエストすればいいと思いました。</em></p>
</blockquote>

<h3 id="medium-private-api-">Medium Private API ✅</h3>

<p>何が Private API か？それはこの API インターフェースが<strong>外部向けではなく、ドキュメントがなく、いつでも停止される可能性があり、法的リスクもある</strong>ということです。つまり、<strong>直接サイトやアプリの動作を解析して呼び出される API を見つけ、自分でプログラムを書いてその API を使い、自分のサービスにデータを取得する</strong>ということです。</p>

<h4 id="httpsmediumcom_graphql"><a href="https://medium.com/_/graphql" target="_blank">https://medium.com/_/graphql</a></h4>

<p>ネットワークリクエストの解析により、すべての Medium API は <a href="https://medium.com/_/graphql" target="_blank">https://medium.com/_/graphql</a> というエンドポイントを使用していることがわかりました。自分のプログラムで同じデータを呼び出して取得できれば、この方法で実現可能です。</p>

<h4 id="medium-private-api--medium-graphql-のスニッフィングフォロワー数取得の例">Medium Private API — Medium Graphql のスニッフィング（フォロワー数取得の例）</h4>

<p>私の最初のアプリケーションは、自分のフォロワー数を取得して自分のポータルサイトに表示することです。</p>

<p><a href="https://link.zhgchg.li/" target="_blank"><strong>link.zhgchg.li</strong></a> <strong>：</strong></p>

<p><img src="/assets/88f0fb935120/1*Lh9a_XR4zvvsaP3y58x9Aw.webp" alt="" loading="lazy" decoding="async" width="963" height="526" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjMiIGhlaWdodD0iNTI2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/88f0fb935120/1*Lh9a_XR4zvvsaP3y58x9Aw.png" /></p>

<p>ですので、自分の Medium アカウントのフォロワー数を取得する必要があります。</p>

<ul>
  <li>
    <p>まずブラウザの「開発者ツール」（Chrome -&gt; 右クリック -&gt; 検証）を開き、「Network」タブに切り替え、「Preserve log」をチェックし、検索欄に「<code class="language-plaintext highlighter-rouge">graphql</code>」と入力します。</p>
  </li>
  <li>
    <p>Mediumアカウントのフォロワーページにアクセス：「 <code class="language-plaintext highlighter-rouge">https://medium.com/@YOUR_USER_NAME/followers</code> 」<br />
このフォロワーURL形式のみで嗅ぎ取り可能であり、<code class="language-plaintext highlighter-rouge">https://YOUR_USER_NAME.medium.com/followers</code> の形式ではFollowers APIを呼び出しません。</p>
  </li>
</ul>

<p><img src="/assets/88f0fb935120/1*jmGbo-BQK9amNmoRneJRPw.webp" alt="" loading="lazy" decoding="async" width="1200" height="848" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/88f0fb935120/1*jmGbo-BQK9amNmoRneJRPw.png" /></p>

<ul>
  <li>
    <p>左側の「graphql」リクエストを一つずつ確認し、「Response」データ内で「<code class="language-plaintext highlighter-rouge">followerCount</code>」というキーワードを検索します。このキーワードを含み、かつ <code class="language-plaintext highlighter-rouge">username</code> がウェブページのユーザー名と一致し、フォロワー数もページに表示されている数と同じリクエストを見つけます。</p>
  </li>
  <li>
    <p>ターゲットの API を見つけたら、Payload -&gt; View Source -&gt; 以下の全内容をコピーしてください。</p>
  </li>
</ul>

<p><img src="/assets/88f0fb935120/1*CGyScjCEe9Cf_3VIJrUJzQ.webp" alt="" loading="lazy" decoding="async" width="1437" height="633" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDM3IiBoZWlnaHQ9IjYzMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/88f0fb935120/1*CGyScjCEe9Cf_3VIJrUJzQ.png" /></p>

<p>現在私たちはMediumのフォロワー取得用APIとペイロードを手に入れたので、<a href="https://www.postman.com/" target="_blank">Postman</a>で試してみましょう！</p>

<h4 id="medium-のフォロワー数取得エンドポイント--リクエスト--レスポンス">Medium のフォロワー数取得エンドポイント — リクエスト &amp; レスポンス</h4>

<p><strong>エンドポイント:</strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>POST https://medium.com/_/graphql
</code></pre></div></div>

<p>Authorization: 認証は不要（トークンやクッキーの設定は不要）</p>

<p><strong>Payload:</strong></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"operationName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"UserFollowers"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"variables"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
            </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
            </span><span class="nl">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"zhgchgli"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"query"</span><span class="p">:</span><span class="w"> </span><span class="s2">"query UserFollowers($username: ID, $id: ID, $paging: PagingOptions) {</span><span class="se">\n</span><span class="s2">  userResult(username: $username, id: $id) {</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    ... on User {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      followersUserConnection(paging: $paging) {</span><span class="se">\n</span><span class="s2">        pagingInfo {</span><span class="se">\n</span><span class="s2">          next {</span><span class="se">\n</span><span class="s2">            from</span><span class="se">\n</span><span class="s2">            limit</span><span class="se">\n</span><span class="s2">            __typename</span><span class="se">\n</span><span class="s2">          }</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        users {</span><span class="se">\n</span><span class="s2">          ...FollowList_publisher</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      ...UserCanonicalizer_user</span><span class="se">\n</span><span class="s2">      ...FollowersHeader_publisher</span><span class="se">\n</span><span class="s2">      ...NoFollows_publisher</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment collectionUrl_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  domain</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CollectionAvatar_collection on Collection {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  avatar {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignInOptions_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignUpOptions_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiModal_collection on Collection {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...SignInOptions_collection</span><span class="se">\n</span><span class="s2">  ...SignUpOptions_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublicationFollowButton_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...SusiModal_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublicationFollowRow_collection on Collection {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  description</span><span class="se">\n</span><span class="s2">  ...CollectionAvatar_collection</span><span class="se">\n</span><span class="s2">  ...PublicationFollowButton_collection</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment userUrl_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  customDomainState {</span><span class="se">\n</span><span class="s2">    live {</span><span class="se">\n</span><span class="s2">      domain</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  hasSubdomain</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserAvatar_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  membership {</span><span class="se">\n</span><span class="s2">    tier</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  ...userUrl_user</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment isUserVerifiedBookAuthor_user on User {</span><span class="se">\n</span><span class="s2">  verifications {</span><span class="se">\n</span><span class="s2">    isBookAuthor</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignInOptions_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignUpOptions_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiModal_user on User {</span><span class="se">\n</span><span class="s2">  ...SignInOptions_user</span><span class="se">\n</span><span class="s2">  ...SignUpOptions_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useNewsletterV3Subscription_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  user {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    username</span><span class="se">\n</span><span class="s2">    newsletterV3 {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useNewsletterV3Subscription_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    ...useNewsletterV3Subscription_newsletterV3</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useAuthorFollowSubscribeButton_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...useNewsletterV3Subscription_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useAuthorFollowSubscribeButton_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...useNewsletterV3Subscription_newsletterV3</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment AuthorFollowSubscribeButton_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  ...SusiModal_user</span><span class="se">\n</span><span class="s2">  ...useAuthorFollowSubscribeButton_user</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...useAuthorFollowSubscribeButton_newsletterV3</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserFollowRow_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  bio</span><span class="se">\n</span><span class="s2">  ...UserAvatar_user</span><span class="se">\n</span><span class="s2">  ...isUserVerifiedBookAuthor_user</span><span class="se">\n</span><span class="s2">  ...AuthorFollowSubscribeButton_user</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment FollowsHeader_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...userUrl_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment FollowList_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    ...PublicationFollowRow_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...UserFollowRow_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserCanonicalizer_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  hasSubdomain</span><span class="se">\n</span><span class="s2">  customDomainState {</span><span class="se">\n</span><span class="s2">    live {</span><span class="se">\n</span><span class="s2">      domain</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment FollowersHeader_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  ...FollowsHeader_publisher</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    subscriberCount</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    socialStats {</span><span class="se">\n</span><span class="s2">      followerCount</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment NoFollows_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n</span><span class="s2">"</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">username</code> : 調べたいユーザー名に変更してください。</p>

<p><a href="https://www.postman.com/" target="_blank"><strong>Postman</strong></a> <strong>：</strong></p>

<p><img src="/assets/88f0fb935120/1*MuntmkeqjFqqD_ma_td3VA.webp" alt="" loading="lazy" decoding="async" width="1200" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwMjQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/88f0fb935120/1*MuntmkeqjFqqD_ma_td3VA.png" /></p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">POST https://medium.com/_/graphql</code></p>
  </li>
  <li>
    <p>Body -&gt; raw -&gt; JSON</p>
  </li>
</ul>

<p><strong>Response:</strong><br />
<strong>レスポンス：</strong></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
        </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
            </span><span class="nl">"userResult"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"User"</span><span class="p">,</span><span class="w">
                </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"8854784154b8"</span><span class="p">,</span><span class="w">
                </span><span class="nl">"followersUserConnection"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"pagingInfo"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                        </span><span class="nl">"next"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                            </span><span class="nl">"from"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1140babdfef7"</span><span class="p">,</span><span class="w">
                            </span><span class="nl">"limit"</span><span class="p">:</span><span class="w"> </span><span class="mi">8</span><span class="p">,</span><span class="w">
                            </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"PageParams"</span><span class="w">
                        </span><span class="p">},</span><span class="w">
                        </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Paging"</span><span class="w">
                    </span><span class="p">},</span><span class="w">
                    </span><span class="nl">"users"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
                        </span><span class="err">///..</span><span class="w"> </span><span class="err">略</span><span class="w">
                    </span><span class="p">],</span><span class="w">
                    </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"UserConnection"</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"zhgchgli"</span><span class="p">,</span><span class="w">
                </span><span class="nl">"hasSubdomain"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
                </span><span class="nl">"customDomainState"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"live"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                        </span><span class="nl">"domain"</span><span class="p">:</span><span class="w"> </span><span class="s2">"zhgchgli.medium.com"</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"CustomDomain"</span><span class="w">
                    </span><span class="p">},</span><span class="w">
                    </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"CustomDomainState"</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ZhgChgLi"</span><span class="p">,</span><span class="w">
                </span><span class="nl">"socialStats"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"followerCount"</span><span class="p">:</span><span class="w"> </span><span class="mi">1050</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"__typename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"SocialStats"</span><span class="w">
                </span><span class="p">}</span><span class="w">
            </span><span class="p">}</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>重要な情報：<code class="language-plaintext highlighter-rouge">response[0]["data"]["userResult"]["socialStats"]["followerCount"]</code> が目的のフォロワー数です！</p>

<p><strong>Ruby デモコード:</strong></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">load_medium_followers</span><span class="p">(</span><span class="n">username</span><span class="p">)</span>
    <span class="k">begin</span>
        <span class="n">url</span> <span class="o">=</span> <span class="s2">"https://medium.com/_/graphql"</span>
        <span class="n">uri</span> <span class="o">=</span> <span class="no">URI</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>

        <span class="n">payload</span> <span class="o">=</span> <span class="p">[</span>
            <span class="p">{</span>
            <span class="s2">"operationName"</span><span class="p">:</span> <span class="s2">"UserFollowers"</span><span class="p">,</span>
            <span class="s2">"variables"</span><span class="p">:</span> <span class="p">{</span>
                <span class="s2">"id"</span><span class="p">:</span> <span class="kp">nil</span><span class="p">,</span>
                <span class="s2">"username"</span><span class="p">:</span> <span class="n">username</span><span class="p">,</span>
                <span class="s2">"paging"</span><span class="p">:</span> <span class="kp">nil</span>
            <span class="p">},</span>
            <span class="s2">"query"</span><span class="p">:</span> <span class="s2">"query UserFollowers($username: ID, $id: ID, $paging: PagingOptions) {</span><span class="se">\n</span><span class="s2">  userResult(username: $username, id: $id) {</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    ... on User {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      followersUserConnection(paging: $paging) {</span><span class="se">\n</span><span class="s2">        pagingInfo {</span><span class="se">\n</span><span class="s2">          next {</span><span class="se">\n</span><span class="s2">            from</span><span class="se">\n</span><span class="s2">            limit</span><span class="se">\n</span><span class="s2">            __typename</span><span class="se">\n</span><span class="s2">          }</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        users {</span><span class="se">\n</span><span class="s2">          ...FollowList_publisher</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      ...UserCanonicalizer_user</span><span class="se">\n</span><span class="s2">      ...FollowersHeader_publisher</span><span class="se">\n</span><span class="s2">      ...NoFollows_publisher</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment collectionUrl_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  domain</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CollectionAvatar_collection on Collection {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  avatar {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignInOptions_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignUpOptions_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiModal_collection on Collection {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...SignInOptions_collection</span><span class="se">\n</span><span class="s2">  ...SignUpOptions_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublicationFollowButton_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...SusiModal_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublicationFollowRow_collection on Collection {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  description</span><span class="se">\n</span><span class="s2">  ...CollectionAvatar_collection</span><span class="se">\n</span><span class="s2">  ...PublicationFollowButton_collection</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment userUrl_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  customDomainState {</span><span class="se">\n</span><span class="s2">    live {</span><span class="se">\n</span><span class="s2">      domain</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  hasSubdomain</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserAvatar_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  membership {</span><span class="se">\n</span><span class="s2">    tier</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  ...userUrl_user</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment isUserVerifiedBookAuthor_user on User {</span><span class="se">\n</span><span class="s2">  verifications {</span><span class="se">\n</span><span class="s2">    isBookAuthor</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignInOptions_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignUpOptions_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiModal_user on User {</span><span class="se">\n</span><span class="s2">  ...SignInOptions_user</span><span class="se">\n</span><span class="s2">  ...SignUpOptions_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useNewsletterV3Subscription_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  user {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    username</span><span class="se">\n</span><span class="s2">    newsletterV3 {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useNewsletterV3Subscription_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    ...useNewsletterV3Subscription_newsletterV3</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useAuthorFollowSubscribeButton_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...useNewsletterV3Subscription_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useAuthorFollowSubscribeButton_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...useNewsletterV3Subscription_newsletterV3</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment AuthorFollowSubscribeButton_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  ...SusiModal_user</span><span class="se">\n</span><span class="s2">  ...useAuthorFollowSubscribeButton_user</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...useAuthorFollowSubscribeButton_newsletterV3</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserFollowRow_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  bio</span><span class="se">\n</span><span class="s2">  ...UserAvatar_user</span><span class="se">\n</span><span class="s2">  ...isUserVerifiedBookAuthor_user</span><span class="se">\n</span><span class="s2">  ...AuthorFollowSubscribeButton_user</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment FollowsHeader_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...userUrl_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment FollowList_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    ...PublicationFollowRow_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...UserFollowRow_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserCanonicalizer_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  hasSubdomain</span><span class="se">\n</span><span class="s2">  customDomainState {</span><span class="se">\n</span><span class="s2">    live {</span><span class="se">\n</span><span class="s2">      domain</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment FollowersHeader_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  ...FollowsHeader_publisher</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    subscriberCount</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    socialStats {</span><span class="se">\n</span><span class="s2">      followerCount</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment NoFollows_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n</span><span class="s2">"</span>
            <span class="p">}</span>
        <span class="p">];</span>

        <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s2">"User-Agent"</span> <span class="o">=&gt;</span> <span class="s2">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0"</span><span class="p">,</span>
            <span class="s2">"Content-Type"</span> <span class="o">=&gt;</span> <span class="s2">"application/json"</span>
        <span class="p">}</span>

        <span class="n">https</span> <span class="o">=</span> <span class="no">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">uri</span><span class="p">.</span><span class="nf">host</span><span class="p">,</span> <span class="n">uri</span><span class="p">.</span><span class="nf">port</span><span class="p">)</span>
        <span class="n">https</span><span class="p">.</span><span class="nf">read_timeout</span> <span class="o">=</span> <span class="mi">30</span>
        <span class="n">https</span><span class="p">.</span><span class="nf">open_timeout</span> <span class="o">=</span> <span class="mi">10</span>
        <span class="n">https</span><span class="p">.</span><span class="nf">use_ssl</span> <span class="o">=</span> <span class="kp">true</span>

        <span class="c1"># --- TLS / 証明書検証の設定 ---</span>
        <span class="c1"># 一部のOpenSSLのビルドや設定ではCRLチェックが有効になっており、</span>
        <span class="c1"># "certificate verify failed (unable to get certificate CRL)" エラーが発生することがあります。</span>
        <span class="c1"># Net::HTTP/OpenSSLはCRLを自動取得しないため、デフォルトの証明書ストアを使用し、</span>
        <span class="c1"># CRL関連のフラグをクリアしてピア証明書の検証を維持しつつ致命的な失敗を回避します。</span>
        <span class="n">https</span><span class="p">.</span><span class="nf">verify_mode</span> <span class="o">=</span> <span class="no">OpenSSL</span><span class="o">::</span><span class="no">SSL</span><span class="o">::</span><span class="no">VERIFY_PEER</span>

        <span class="n">store</span> <span class="o">=</span> <span class="no">OpenSSL</span><span class="o">::</span><span class="no">X509</span><span class="o">::</span><span class="no">Store</span><span class="p">.</span><span class="nf">new</span>
        <span class="n">store</span><span class="p">.</span><span class="nf">set_default_paths</span>
        <span class="c1"># デフォルトでCRLチェックフラグが有効にならないように設定</span>
        <span class="n">store</span><span class="p">.</span><span class="nf">flags</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="n">https</span><span class="p">.</span><span class="nf">cert_store</span> <span class="o">=</span> <span class="n">store</span>

        <span class="c1"># 必要に応じて環境変数でCAバンドルのパスを上書き可能</span>
        <span class="k">if</span> <span class="no">ENV</span><span class="p">[</span><span class="s1">'SSL_CERT_FILE'</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="no">ENV</span><span class="p">[</span><span class="s1">'SSL_CERT_FILE'</span><span class="p">].</span><span class="nf">empty?</span>
        <span class="n">https</span><span class="p">.</span><span class="nf">ca_file</span> <span class="o">=</span> <span class="no">ENV</span><span class="p">[</span><span class="s1">'SSL_CERT_FILE'</span><span class="p">]</span>
        <span class="k">end</span>
        <span class="k">if</span> <span class="no">ENV</span><span class="p">[</span><span class="s1">'SSL_CERT_DIR'</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="no">ENV</span><span class="p">[</span><span class="s1">'SSL_CERT_DIR'</span><span class="p">].</span><span class="nf">empty?</span>
        <span class="n">https</span><span class="p">.</span><span class="nf">ca_path</span> <span class="o">=</span> <span class="no">ENV</span><span class="p">[</span><span class="s1">'SSL_CERT_DIR'</span><span class="p">]</span>
        <span class="k">end</span>

        <span class="c1"># (任意) ネットワーク問題によるハングを防ぐタイムアウト設定</span>
        <span class="n">https</span><span class="p">.</span><span class="nf">open_timeout</span> <span class="o">=</span> <span class="mi">10</span>
        <span class="n">https</span><span class="p">.</span><span class="nf">read_timeout</span> <span class="o">=</span> <span class="mi">30</span>
        <span class="c1"># --- TLS設定ここまで ---</span>


        <span class="n">req</span> <span class="o">=</span> <span class="no">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="o">::</span><span class="no">Post</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">uri</span><span class="p">.</span><span class="nf">request_uri</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
        <span class="n">req</span><span class="p">.</span><span class="nf">body</span> <span class="o">=</span> <span class="no">JSON</span><span class="p">.</span><span class="nf">dump</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>

        <span class="n">res</span> <span class="o">=</span> <span class="n">https</span><span class="p">.</span><span class="nf">request</span><span class="p">(</span><span class="n">req</span><span class="p">)</span>

        <span class="n">json</span> <span class="o">=</span> <span class="no">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="nf">body</span><span class="p">)</span>
        <span class="n">count</span> <span class="o">=</span> <span class="n">json</span><span class="o">&amp;</span><span class="p">.</span><span class="nf">dig</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s2">"data"</span><span class="p">,</span> <span class="s2">"userResult"</span><span class="p">,</span> <span class="s2">"socialStats"</span><span class="p">,</span> <span class="s2">"followerCount"</span><span class="p">)</span>
        <span class="n">count</span> <span class="p">?</span> <span class="n">count</span><span class="p">.</span><span class="nf">to_i</span> <span class="p">:</span> <span class="mi">0</span>
        <span class="k">return</span> <span class="s2">"1K+"</span> <span class="k">unless</span> <span class="n">count</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">&gt;</span> <span class="mi">0</span>
        <span class="k">return</span> <span class="s2">"</span><span class="si">#{</span><span class="n">count</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">reverse</span><span class="p">.</span><span class="nf">gsub</span><span class="p">(</span><span class="sr">/(\d{3})(?=\d)/</span><span class="p">,</span> <span class="s1">'\\1,'</span><span class="p">).</span><span class="nf">reverse</span><span class="si">}</span><span class="s2">+"</span>
    <span class="k">rescue</span> <span class="o">=&gt;</span> <span class="n">e</span>
        <span class="s2">"1K+"</span>
    <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<h4 id="medium-private-api--アカウントのすべての記事を取得する">Medium Private API — アカウントのすべての記事を取得する</h4>

<p>同じ方法で、ターゲットアカウントの投稿一覧も取得できます。</p>

<p>Graphql クエリ本文:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"operationName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"UserProfileQuery"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"variables"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"homepagePostsFrom"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
          </span><span class="nl">"includeDistributedResponses"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
          </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"8854784154b8"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"homepagePostsLimit"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"query"</span><span class="p">:</span><span class="w"> </span><span class="s2">"query UserProfileQuery($id: ID, $username: ID, $homepagePostsLimit: PaginationLimit, $homepagePostsFrom: String = null, $includeDistributedResponses: Boolean = true) {</span><span class="se">\n</span><span class="s2">  userResult(id: $id, username: $username) {</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    ... on User {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      name</span><span class="se">\n</span><span class="s2">      viewerIsUser</span><span class="se">\n</span><span class="s2">      viewerEdge {</span><span class="se">\n</span><span class="s2">        id</span><span class="se">\n</span><span class="s2">        isFollowing</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      homePostsPublished: homepagePostsConnection(paging: {limit: 1}) {</span><span class="se">\n</span><span class="s2">        posts {</span><span class="se">\n</span><span class="s2">          id</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      ...UserCanonicalizer_user</span><span class="se">\n</span><span class="s2">      ...UserProfileScreen_user</span><span class="se">\n</span><span class="s2">      ...EntityDrivenSubscriptionLandingPageScreen_writer</span><span class="se">\n</span><span class="s2">      ...useShouldShowEntityDrivenSubscription_creator</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserCanonicalizer_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  hasSubdomain</span><span class="se">\n</span><span class="s2">  customDomainState {</span><span class="se">\n</span><span class="s2">    live {</span><span class="se">\n</span><span class="s2">      domain</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserProfileScreen_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  viewerIsUser</span><span class="se">\n</span><span class="s2">  ...PublisherHeader_publisher</span><span class="se">\n</span><span class="s2">  ...PublisherHomePosts_publisher</span><span class="se">\n</span><span class="s2">  ...UserSubdomainFlow_user</span><span class="se">\n</span><span class="s2">  ...UserProfileMetadata_user</span><span class="se">\n</span><span class="s2">  ...SuspendedBannerLoader_user</span><span class="se">\n</span><span class="s2">  ...ExpandablePost_user</span><span class="se">\n</span><span class="s2">  ...useAnalytics_user</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHeader_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...PublisherHeaderBackground_publisher</span><span class="se">\n</span><span class="s2">  ...PublisherHeaderNameplate_publisher</span><span class="se">\n</span><span class="s2">  ...PublisherHeaderActions_publisher</span><span class="se">\n</span><span class="s2">  ...PublisherHeaderNav_publisher</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHeaderBackground_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  customStyleSheet {</span><span class="se">\n</span><span class="s2">    ...PublisherHeaderBackground_customStyleSheet</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    colorPalette {</span><span class="se">\n</span><span class="s2">      tintBackgroundSpectrum {</span><span class="se">\n</span><span class="s2">        backgroundColor</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    isAuroraVisible</span><span class="se">\n</span><span class="s2">    legacyHeaderBackgroundImage {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      originalWidth</span><span class="se">\n</span><span class="s2">      focusPercentX</span><span class="se">\n</span><span class="s2">      focusPercentY</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    ...collectionTintBackgroundTheme_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...publisherUrl_publisher</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHeaderBackground_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  global {</span><span class="se">\n</span><span class="s2">    colorPalette {</span><span class="se">\n</span><span class="s2">      background {</span><span class="se">\n</span><span class="s2">        rgb</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  header {</span><span class="se">\n</span><span class="s2">    headerScale</span><span class="se">\n</span><span class="s2">    backgroundImageDisplayMode</span><span class="se">\n</span><span class="s2">    backgroundImageVerticalAlignment</span><span class="se">\n</span><span class="s2">    backgroundColorDisplayMode</span><span class="se">\n</span><span class="s2">    backgroundColor {</span><span class="se">\n</span><span class="s2">      alpha</span><span class="se">\n</span><span class="s2">      rgb</span><span class="se">\n</span><span class="s2">      ...getHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">      ...getOpaqueHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    secondaryBackgroundColor {</span><span class="se">\n</span><span class="s2">      ...getHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    postBackgroundColor {</span><span class="se">\n</span><span class="s2">      ...getHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    backgroundImage {</span><span class="se">\n</span><span class="s2">      ...MetaHeaderBackground_imageMetadata</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getHexFromColorValue_colorValue on ColorValue {</span><span class="se">\n</span><span class="s2">  rgb</span><span class="se">\n</span><span class="s2">  alpha</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getOpaqueHexFromColorValue_colorValue on ColorValue {</span><span class="se">\n</span><span class="s2">  rgb</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderBackground_imageMetadata on ImageMetadata {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  originalWidth</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment collectionTintBackgroundTheme_collection on Collection {</span><span class="se">\n</span><span class="s2">  colorPalette {</span><span class="se">\n</span><span class="s2">    ...collectionTintBackgroundTheme_colorPalette</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  customStyleSheet {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...collectionTintBackgroundTheme_customStyleSheet</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment collectionTintBackgroundTheme_colorPalette on ColorPalette {</span><span class="se">\n</span><span class="s2">  ...customTintBackgroundTheme_colorPalette</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment customTintBackgroundTheme_colorPalette on ColorPalette {</span><span class="se">\n</span><span class="s2">  tintBackgroundSpectrum {</span><span class="se">\n</span><span class="s2">    ...ThemeUtil_colorSpectrum</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ThemeUtil_colorSpectrum on ColorSpectrum {</span><span class="se">\n</span><span class="s2">  backgroundColor</span><span class="se">\n</span><span class="s2">  ...ThemeUtilInterpolateHelpers_colorSpectrum</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ThemeUtilInterpolateHelpers_colorSpectrum on ColorSpectrum {</span><span class="se">\n</span><span class="s2">  colorPoints {</span><span class="se">\n</span><span class="s2">    ...ThemeUtil_colorPoint</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ThemeUtil_colorPoint on ColorPoint {</span><span class="se">\n</span><span class="s2">  color</span><span class="se">\n</span><span class="s2">  point</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment collectionTintBackgroundTheme_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...customTintBackgroundTheme_customStyleSheet</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment customTintBackgroundTheme_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  global {</span><span class="se">\n</span><span class="s2">    colorPalette {</span><span class="se">\n</span><span class="s2">      primary {</span><span class="se">\n</span><span class="s2">        colorPalette {</span><span class="se">\n</span><span class="s2">          ...customTintBackgroundTheme_colorPalette</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment publisherUrl_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...userUrl_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment collectionUrl_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  domain</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment userUrl_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  customDomainState {</span><span class="se">\n</span><span class="s2">    live {</span><span class="se">\n</span><span class="s2">      domain</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  hasSubdomain</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHeaderNameplate_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  ...PublisherAvatar_publisher</span><span class="se">\n</span><span class="s2">  ...PublisherHeaderLogo_publisher</span><span class="se">\n</span><span class="s2">  ...PublisherFollowerCount_publisher</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherAvatar_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...CollectionAvatar_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...UserAvatar_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CollectionAvatar_collection on Collection {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  avatar {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserAvatar_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  mediumMemberAt</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  ...userUrl_user</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHeaderLogo_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  customStyleSheet {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    header {</span><span class="se">\n</span><span class="s2">      logoImage {</span><span class="se">\n</span><span class="s2">        id</span><span class="se">\n</span><span class="s2">        originalHeight</span><span class="se">\n</span><span class="s2">        originalWidth</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      appNameColor {</span><span class="se">\n</span><span class="s2">        ...getHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      appNameTreatment</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    isAuroraVisible</span><span class="se">\n</span><span class="s2">    logo {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      originalHeight</span><span class="se">\n</span><span class="s2">      originalWidth</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...CustomHeaderTooltip_publisher</span><span class="se">\n</span><span class="s2">  ...publisherUrl_publisher</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CustomHeaderTooltip_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  customStyleSheet {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    header {</span><span class="se">\n</span><span class="s2">      appNameTreatment</span><span class="se">\n</span><span class="s2">      nameTreatment</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    isAuroraVisible</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherFollowerCount_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    subscriberCount</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    socialStats {</span><span class="se">\n</span><span class="s2">      followerCount</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    username</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHeaderActions_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ...MetaHeaderPubMenu_publisher</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    ...CollectionFollowButton_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...FollowAndSubscribeButtons_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderPubMenu_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    ...MetaHeaderPubMenu_publisher_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...MetaHeaderPubMenu_publisher_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderPubMenu_publisher_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  domain</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...MutePopoverOptions_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MutePopoverOptions_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderPubMenu_publisher_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  ...MutePopoverOptions_creator</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MutePopoverOptions_creator on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CollectionFollowButton_collection on Collection {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">  ...SusiClickable_collection</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiClickable_collection on Collection {</span><span class="se">\n</span><span class="s2">  ...SusiContainer_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiContainer_collection on Collection {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...SignInOptions_collection</span><span class="se">\n</span><span class="s2">  ...SignUpOptions_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignInOptions_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignUpOptions_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment FollowAndSubscribeButtons_user on User {</span><span class="se">\n</span><span class="s2">  ...UserFollowButton_user</span><span class="se">\n</span><span class="s2">  ...UserSubscribeButton_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserFollowButton_user on User {</span><span class="se">\n</span><span class="s2">  ...UserFollowButtonSignedIn_user</span><span class="se">\n</span><span class="s2">  ...UserFollowButtonSignedOut_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserFollowButtonSignedIn_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserFollowButtonSignedOut_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...SusiClickable_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiClickable_user on User {</span><span class="se">\n</span><span class="s2">  ...SusiContainer_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiContainer_user on User {</span><span class="se">\n</span><span class="s2">  ...SignInOptions_user</span><span class="se">\n</span><span class="s2">  ...SignUpOptions_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignInOptions_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignUpOptions_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserSubscribeButton_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  isPartnerProgramEnrolled</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  viewerEdge {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    isFollowing</span><span class="se">\n</span><span class="s2">    isUser</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  viewerIsUser</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...useNewsletterV3Subscription_newsletterV3</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...useNewsletterV3Subscription_user</span><span class="se">\n</span><span class="s2">  ...MembershipUpsellModal_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useNewsletterV3Subscription_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  user {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    username</span><span class="se">\n</span><span class="s2">    newsletterV3 {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useNewsletterV3Subscription_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    ...useNewsletterV3Subscription_newsletterV3</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MembershipUpsellModal_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  postSubscribeMembershipUpsellShownAt</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHeaderNav_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  customStyleSheet {</span><span class="se">\n</span><span class="s2">    navigation {</span><span class="se">\n</span><span class="s2">      navItems {</span><span class="se">\n</span><span class="s2">        name</span><span class="se">\n</span><span class="s2">        ...PublisherHeaderNavLink_headerNavigationItem</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...PublisherHeaderNavLink_publisher</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    domain</span><span class="se">\n</span><span class="s2">    isAuroraVisible</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    navItems {</span><span class="se">\n</span><span class="s2">      tagSlug</span><span class="se">\n</span><span class="s2">      title</span><span class="se">\n</span><span class="s2">      url</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    customDomainState {</span><span class="se">\n</span><span class="s2">      live {</span><span class="se">\n</span><span class="s2">        domain</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    hasSubdomain</span><span class="se">\n</span><span class="s2">    username</span><span class="se">\n</span><span class="s2">    about</span><span class="se">\n</span><span class="s2">    homePostsPublished: homepagePostsConnection(paging: {limit: 1}) {</span><span class="se">\n</span><span class="s2">      posts {</span><span class="se">\n</span><span class="s2">        id</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHeaderNavLink_headerNavigationItem on HeaderNavigationItem {</span><span class="se">\n</span><span class="s2">  href</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  tags {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    normalizedTagSlug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHeaderNavLink_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHomePosts_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  homepagePostsConnection(</span><span class="se">\n</span><span class="s2">    paging: {limit: $homepagePostsLimit, from: $homepagePostsFrom}</span><span class="se">\n</span><span class="s2">    includeDistributedResponses: $includeDistributedResponses</span><span class="se">\n</span><span class="s2">  ) {</span><span class="se">\n</span><span class="s2">    posts {</span><span class="se">\n</span><span class="s2">      ...PublisherHomePosts_post</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    pagingInfo {</span><span class="se">\n</span><span class="s2">      next {</span><span class="se">\n</span><span class="s2">        from</span><span class="se">\n</span><span class="s2">        limit</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...CardByline_publisher</span><span class="se">\n</span><span class="s2">  ...NewsletterV3Promo_publisher</span><span class="se">\n</span><span class="s2">  ...PublisherHomePosts_user</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHomePosts_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...ExpandablePost_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ExpandablePost_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    ...ExpandablePost_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    ...CardByline_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...InteractivePostBody_postPreview</span><span class="se">\n</span><span class="s2">  firstPublishedAt</span><span class="se">\n</span><span class="s2">  isLocked</span><span class="se">\n</span><span class="s2">  isSeries</span><span class="se">\n</span><span class="s2">  isShortform</span><span class="se">\n</span><span class="s2">  latestPublishedAt</span><span class="se">\n</span><span class="s2">  inResponseToCatalogResult {</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  mediumUrl</span><span class="se">\n</span><span class="s2">  postResponses {</span><span class="se">\n</span><span class="s2">    count</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  previewImage {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    focusPercentX</span><span class="se">\n</span><span class="s2">    focusPercentY</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  readingTime</span><span class="se">\n</span><span class="s2">  sequence {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  title</span><span class="se">\n</span><span class="s2">  uniqueSlug</span><span class="se">\n</span><span class="s2">  visibility</span><span class="se">\n</span><span class="s2">  ...CardByline_post</span><span class="se">\n</span><span class="s2">  ...ExpandablePostFooter_post</span><span class="se">\n</span><span class="s2">  ...InResponseToEntityPreview_post</span><span class="se">\n</span><span class="s2">  ...PostScrollTracker_post</span><span class="se">\n</span><span class="s2">  ...ReadMore_post</span><span class="se">\n</span><span class="s2">  ...HighDensityPreview_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ExpandablePost_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  ...CardByline_user</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CardByline_user on User {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  mediumMemberAt</span><span class="se">\n</span><span class="s2">  socialStats {</span><span class="se">\n</span><span class="s2">    followerCount</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...userUrl_user</span><span class="se">\n</span><span class="s2">  ...UserMentionTooltip_user</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserMentionTooltip_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  bio</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  mediumMemberAt</span><span class="se">\n</span><span class="s2">  ...UserAvatar_user</span><span class="se">\n</span><span class="s2">  ...UserFollowButton_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CardByline_collection on Collection {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment InteractivePostBody_postPreview on Post {</span><span class="se">\n</span><span class="s2">  extendedPreviewContent(</span><span class="se">\n</span><span class="s2">    truncationConfig: {previewParagraphsWordCountThreshold: 400, minimumWordLengthForTruncation: 150, truncateAtEndOfSentence: true, showFullImageCaptions: true, shortformPreviewParagraphsWordCountThreshold: 30, shortformMinimumWordLengthForTruncation: 30}</span><span class="se">\n</span><span class="s2">  ) {</span><span class="se">\n</span><span class="s2">    bodyModel {</span><span class="se">\n</span><span class="s2">      ...PostBody_bodyModel</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    isFullContent</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostBody_bodyModel on RichText {</span><span class="se">\n</span><span class="s2">  sections {</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    startIndex</span><span class="se">\n</span><span class="s2">    textLayout</span><span class="se">\n</span><span class="s2">    imageLayout</span><span class="se">\n</span><span class="s2">    backgroundImage {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      originalHeight</span><span class="se">\n</span><span class="s2">      originalWidth</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    videoLayout</span><span class="se">\n</span><span class="s2">    backgroundVideo {</span><span class="se">\n</span><span class="s2">      videoId</span><span class="se">\n</span><span class="s2">      originalHeight</span><span class="se">\n</span><span class="s2">      originalWidth</span><span class="se">\n</span><span class="s2">      previewImageId</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...PostBodySection_paragraph</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...normalizedBodyModel_richText</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostBodySection_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...PostBodyParagraph_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostBodyParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  ...ImageParagraph_paragraph</span><span class="se">\n</span><span class="s2">  ...TextParagraph_paragraph</span><span class="se">\n</span><span class="s2">  ...IframeParagraph_paragraph</span><span class="se">\n</span><span class="s2">  ...MixtapeParagraph_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ImageParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  href</span><span class="se">\n</span><span class="s2">  layout</span><span class="se">\n</span><span class="s2">  metadata {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    originalHeight</span><span class="se">\n</span><span class="s2">    originalWidth</span><span class="se">\n</span><span class="s2">    focusPercentX</span><span class="se">\n</span><span class="s2">    focusPercentY</span><span class="se">\n</span><span class="s2">    alt</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...Markups_paragraph</span><span class="se">\n</span><span class="s2">  ...ParagraphRefsMapContext_paragraph</span><span class="se">\n</span><span class="s2">  ...PostAnnotationsMarker_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment Markups_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  text</span><span class="se">\n</span><span class="s2">  hasDropCap</span><span class="se">\n</span><span class="s2">  dropCapImage {</span><span class="se">\n</span><span class="s2">    ...MarkupNode_data_dropCapImage</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  markups {</span><span class="se">\n</span><span class="s2">    type</span><span class="se">\n</span><span class="s2">    start</span><span class="se">\n</span><span class="s2">    end</span><span class="se">\n</span><span class="s2">    href</span><span class="se">\n</span><span class="s2">    anchorType</span><span class="se">\n</span><span class="s2">    userId</span><span class="se">\n</span><span class="s2">    linkMetadata {</span><span class="se">\n</span><span class="s2">      httpStatus</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MarkupNode_data_dropCapImage on ImageMetadata {</span><span class="se">\n</span><span class="s2">  ...DropCap_image</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment DropCap_image on ImageMetadata {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  originalHeight</span><span class="se">\n</span><span class="s2">  originalWidth</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ParagraphRefsMapContext_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  text</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostAnnotationsMarker_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  ...PostViewNoteCard_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostViewNoteCard_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment TextParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  hasDropCap</span><span class="se">\n</span><span class="s2">  ...Markups_paragraph</span><span class="se">\n</span><span class="s2">  ...ParagraphRefsMapContext_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment IframeParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  iframe {</span><span class="se">\n</span><span class="s2">    mediaResource {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      iframeSrc</span><span class="se">\n</span><span class="s2">      iframeHeight</span><span class="se">\n</span><span class="s2">      iframeWidth</span><span class="se">\n</span><span class="s2">      title</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  layout</span><span class="se">\n</span><span class="s2">  ...getEmbedlyCardUrlParams_paragraph</span><span class="se">\n</span><span class="s2">  ...Markups_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getEmbedlyCardUrlParams_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  iframe {</span><span class="se">\n</span><span class="s2">    mediaResource {</span><span class="se">\n</span><span class="s2">      iframeSrc</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MixtapeParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  mixtapeMetadata {</span><span class="se">\n</span><span class="s2">    href</span><span class="se">\n</span><span class="s2">    mediaResource {</span><span class="se">\n</span><span class="s2">      mediumCatalog {</span><span class="se">\n</span><span class="s2">        id</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...GenericMixtapeParagraph_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment GenericMixtapeParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  text</span><span class="se">\n</span><span class="s2">  mixtapeMetadata {</span><span class="se">\n</span><span class="s2">    href</span><span class="se">\n</span><span class="s2">    thumbnailImageId</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  markups {</span><span class="se">\n</span><span class="s2">    start</span><span class="se">\n</span><span class="s2">    end</span><span class="se">\n</span><span class="s2">    type</span><span class="se">\n</span><span class="s2">    href</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment normalizedBodyModel_richText on RichText {</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    markups {</span><span class="se">\n</span><span class="s2">      type</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    ...getParagraphHighlights_paragraph</span><span class="se">\n</span><span class="s2">    ...getParagraphPrivateNotes_paragraph</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  sections {</span><span class="se">\n</span><span class="s2">    startIndex</span><span class="se">\n</span><span class="s2">    ...getSectionEndIndex_section</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...getParagraphStyles_richText</span><span class="se">\n</span><span class="s2">  ...getParagraphSpaces_richText</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getParagraphHighlights_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getParagraphPrivateNotes_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getSectionEndIndex_section on Section {</span><span class="se">\n</span><span class="s2">  startIndex</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getParagraphStyles_richText on RichText {</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    text</span><span class="se">\n</span><span class="s2">    type</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  sections {</span><span class="se">\n</span><span class="s2">    ...getSectionEndIndex_section</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getParagraphSpaces_richText on RichText {</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    layout</span><span class="se">\n</span><span class="s2">    metadata {</span><span class="se">\n</span><span class="s2">      originalHeight</span><span class="se">\n</span><span class="s2">      originalWidth</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    type</span><span class="se">\n</span><span class="s2">    ...paragraphExtendsImageGrid_paragraph</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...getSeriesParagraphTopSpacings_richText</span><span class="se">\n</span><span class="s2">  ...getPostParagraphTopSpacings_richText</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment paragraphExtendsImageGrid_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  layout</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getSeriesParagraphTopSpacings_richText on RichText {</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  sections {</span><span class="se">\n</span><span class="s2">    startIndex</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getPostParagraphTopSpacings_richText on RichText {</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    layout</span><span class="se">\n</span><span class="s2">    text</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  sections {</span><span class="se">\n</span><span class="s2">    startIndex</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CardByline_post on Post {</span><span class="se">\n</span><span class="s2">  ...DraftStatus_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment DraftStatus_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  pendingCollection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    creator {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    ...BoldCollectionName_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  statusForCollection</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  isPublished</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment BoldCollectionName_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ExpandablePostFooter_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  allowResponses</span><span class="se">\n</span><span class="s2">  postResponses {</span><span class="se">\n</span><span class="s2">    count</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  isLimitedState</span><span class="se">\n</span><span class="s2">  ...ExpandablePostCardOverflowButton_post</span><span class="se">\n</span><span class="s2">  ...BookmarkButton_post</span><span class="se">\n</span><span class="s2">  ...PostFooterSocialPopover_post</span><span class="se">\n</span><span class="s2">  ...MultiVote_post</span><span class="se">\n</span><span class="s2">  ...OverflowMenuButtonWithNegativeSignal_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ExpandablePostCardOverflowButton_post on Post {</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...ExpandablePostCardEditorWriterButton_post</span><span class="se">\n</span><span class="s2">  ...ExpandablePostCardReaderButton_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ExpandablePostCardEditorWriterButton_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  allowResponses</span><span class="se">\n</span><span class="s2">  clapCount</span><span class="se">\n</span><span class="s2">  visibility</span><span class="se">\n</span><span class="s2">  mediumUrl</span><span class="se">\n</span><span class="s2">  responseDistribution</span><span class="se">\n</span><span class="s2">  ...useIsPinnedInContext_post</span><span class="se">\n</span><span class="s2">  ...CopyFriendLinkMenuItem_post</span><span class="se">\n</span><span class="s2">  ...NewsletterV3EmailToSubscribersMenuItem_post</span><span class="se">\n</span><span class="s2">  ...OverflowMenuItemUndoClaps_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useIsPinnedInContext_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  pendingCollection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  pinnedAt</span><span class="se">\n</span><span class="s2">  pinnedByCreatorAt</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CopyFriendLinkMenuItem_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment NewsletterV3EmailToSubscribersMenuItem_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    newsletterV3 {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      subscribersCount</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  isNewsletter</span><span class="se">\n</span><span class="s2">  isAuthorNewsletter</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment OverflowMenuItemUndoClaps_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  clapCount</span><span class="se">\n</span><span class="s2">  ...ClapMutation_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ClapMutation_post on Post {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  clapCount</span><span class="se">\n</span><span class="s2">  ...MultiVoteCount_post</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MultiVoteCount_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...PostVotersNetwork_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostVotersNetwork_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  voterCount</span><span class="se">\n</span><span class="s2">  recommenders {</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ExpandablePostCardReaderButton_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  clapCount</span><span class="se">\n</span><span class="s2">  ...ClapMutation_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment BookmarkButton_post on Post {</span><span class="se">\n</span><span class="s2">  visibility</span><span class="se">\n</span><span class="s2">  ...SusiClickable_post</span><span class="se">\n</span><span class="s2">  ...AddToCatalogBookmarkButton_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiClickable_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  mediumUrl</span><span class="se">\n</span><span class="s2">  ...SusiContainer_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiContainer_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment AddToCatalogBookmarkButton_post on Post {</span><span class="se">\n</span><span class="s2">  ...AddToCatalogBase_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment AddToCatalogBase_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostFooterSocialPopover_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  mediumUrl</span><span class="se">\n</span><span class="s2">  title</span><span class="se">\n</span><span class="s2">  ...SharePostButton_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SharePostButton_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MultiVote_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  clapCount</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...SusiClickable_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  isPublished</span><span class="se">\n</span><span class="s2">  ...SusiClickable_post</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  isLimitedState</span><span class="se">\n</span><span class="s2">  ...MultiVoteCount_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment OverflowMenuButtonWithNegativeSignal_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...OverflowMenuWithNegativeSignal_post</span><span class="se">\n</span><span class="s2">  ...CreatorActionOverflowPopover_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment OverflowMenuWithNegativeSignal_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...OverflowMenuItemUndoClaps_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CreatorActionOverflowPopover_post on Post {</span><span class="se">\n</span><span class="s2">  allowResponses</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  statusForCollection</span><span class="se">\n</span><span class="s2">  isLocked</span><span class="se">\n</span><span class="s2">  isPublished</span><span class="se">\n</span><span class="s2">  clapCount</span><span class="se">\n</span><span class="s2">  mediumUrl</span><span class="se">\n</span><span class="s2">  pinnedAt</span><span class="se">\n</span><span class="s2">  pinnedByCreatorAt</span><span class="se">\n</span><span class="s2">  curationEligibleAt</span><span class="se">\n</span><span class="s2">  mediumUrl</span><span class="se">\n</span><span class="s2">  responseDistribution</span><span class="se">\n</span><span class="s2">  visibility</span><span class="se">\n</span><span class="s2">  inResponseToPostResult {</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  inResponseToCatalogResult {</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  pendingCollection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    creator {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    avatar {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    domain</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...MutePopoverOptions_creator</span><span class="se">\n</span><span class="s2">    ...auroraHooks_publisher</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    creator {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    avatar {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    domain</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    ...MutePopoverOptions_collection</span><span class="se">\n</span><span class="s2">    ...auroraHooks_publisher</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...useIsPinnedInContext_post</span><span class="se">\n</span><span class="s2">  ...NewsletterV3EmailToSubscribersMenuItem_post</span><span class="se">\n</span><span class="s2">  ...OverflowMenuItemUndoClaps_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment auroraHooks_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    isAuroraEligible</span><span class="se">\n</span><span class="s2">    isAuroraVisible</span><span class="se">\n</span><span class="s2">    viewerEdge {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      isEditor</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    isAuroraVisible</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment InResponseToEntityPreview_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  inResponseToEntityType</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostScrollTracker_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  sequence {</span><span class="se">\n</span><span class="s2">    sequenceId</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ReadMore_post on Post {</span><span class="se">\n</span><span class="s2">  mediumUrl</span><span class="se">\n</span><span class="s2">  readingTime</span><span class="se">\n</span><span class="s2">  ...usePostUrl_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment usePostUrl_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    ...userUrl_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    domain</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  isSeries</span><span class="se">\n</span><span class="s2">  mediumUrl</span><span class="se">\n</span><span class="s2">  sequence {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  uniqueSlug</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment HighDensityPreview_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  title</span><span class="se">\n</span><span class="s2">  previewImage {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    focusPercentX</span><span class="se">\n</span><span class="s2">    focusPercentY</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  extendedPreviewContent(</span><span class="se">\n</span><span class="s2">    truncationConfig: {previewParagraphsWordCountThreshold: 400, minimumWordLengthForTruncation: 150, truncateAtEndOfSentence: true, showFullImageCaptions: true, shortformPreviewParagraphsWordCountThreshold: 30, shortformMinimumWordLengthForTruncation: 30}</span><span class="se">\n</span><span class="s2">  ) {</span><span class="se">\n</span><span class="s2">    subtitle</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...HighDensityFooter_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment HighDensityFooter_post on Post {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  readingTime</span><span class="se">\n</span><span class="s2">  tags {</span><span class="se">\n</span><span class="s2">    ...TopicPill_tag</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...BookmarkButton_post</span><span class="se">\n</span><span class="s2">  ...ExpandablePostCardOverflowButton_post</span><span class="se">\n</span><span class="s2">  ...OverflowMenuButtonWithNegativeSignal_post</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment TopicPill_tag on Tag {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  displayTitle</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CardByline_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...CardByline_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...CardByline_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment NewsletterV3Promo_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...NewsletterV3Promo_publisher_User</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    ...NewsletterV3Promo_publisher_Collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment NewsletterV3Promo_publisher_User on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  viewerIsUser</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...NewsletterV3Promo_newsletterV3</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment NewsletterV3Promo_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  description</span><span class="se">\n</span><span class="s2">  promoHeadline</span><span class="se">\n</span><span class="s2">  promoBody</span><span class="se">\n</span><span class="s2">  ...NewsletterV3AmpButton_newsletterV3</span><span class="se">\n</span><span class="s2">  ...NewsletterV3SubscribeButton_newsletterV3</span><span class="se">\n</span><span class="s2">  ...NewsletterV3SubscribeByEmail_newsletterV3</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment NewsletterV3AmpButton_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    ...collectionDefaultBackgroundTheme_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment collectionDefaultBackgroundTheme_collection on Collection {</span><span class="se">\n</span><span class="s2">  colorPalette {</span><span class="se">\n</span><span class="s2">    ...collectionDefaultBackgroundTheme_colorPalette</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  customStyleSheet {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...collectionDefaultBackgroundTheme_customStyleSheet</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment collectionDefaultBackgroundTheme_colorPalette on ColorPalette {</span><span class="se">\n</span><span class="s2">  ...customDefaultBackgroundTheme_colorPalette</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment customDefaultBackgroundTheme_colorPalette on ColorPalette {</span><span class="se">\n</span><span class="s2">  highlightSpectrum {</span><span class="se">\n</span><span class="s2">    ...ThemeUtil_colorSpectrum</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  defaultBackgroundSpectrum {</span><span class="se">\n</span><span class="s2">    ...ThemeUtil_colorSpectrum</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  tintBackgroundSpectrum {</span><span class="se">\n</span><span class="s2">    ...ThemeUtil_colorSpectrum</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment collectionDefaultBackgroundTheme_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...customDefaultBackgroundTheme_customStyleSheet</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment customDefaultBackgroundTheme_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  global {</span><span class="se">\n</span><span class="s2">    colorPalette {</span><span class="se">\n</span><span class="s2">      primary {</span><span class="se">\n</span><span class="s2">        colorPalette {</span><span class="se">\n</span><span class="s2">          ...customDefaultBackgroundTheme_colorPalette</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      background {</span><span class="se">\n</span><span class="s2">        colorPalette {</span><span class="se">\n</span><span class="s2">          ...customDefaultBackgroundTheme_colorPalette</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment NewsletterV3SubscribeButton_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  user {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    username</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    ...SusiClickable_collection</span><span class="se">\n</span><span class="s2">    ...collectionDefaultBackgroundTheme_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...SusiClickable_newsletterV3</span><span class="se">\n</span><span class="s2">  ...useNewsletterV3Subscription_newsletterV3</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiClickable_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  ...SusiContainer_newsletterV3</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SusiContainer_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  ...SignInOptions_newsletterV3</span><span class="se">\n</span><span class="s2">  ...SignUpOptions_newsletterV3</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignInOptions_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SignUpOptions_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment NewsletterV3SubscribeByEmail_newsletterV3 on NewsletterV3 {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  user {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    username</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  collection {</span><span class="se">\n</span><span class="s2">    ...collectionDefaultBackgroundTheme_collection</span><span class="se">\n</span><span class="s2">    ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment NewsletterV3Promo_publisher_Collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  domain</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...NewsletterV3Promo_newsletterV3</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherHomePosts_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...useShowAuthorNewsletterV3Promo_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useShowAuthorNewsletterV3Promo_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    showPromo</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserSubdomainFlow_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  hasCompletedProfile</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  bio</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  ...UserCompleteProfileDialog_user</span><span class="se">\n</span><span class="s2">  ...UserSubdomainOnboardingDialog_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserCompleteProfileDialog_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  bio</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  hasCompletedProfile</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserSubdomainOnboardingDialog_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  customDomainState {</span><span class="se">\n</span><span class="s2">    pending {</span><span class="se">\n</span><span class="s2">      status</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    live {</span><span class="se">\n</span><span class="s2">      status</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserProfileMetadata_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  bio</span><span class="se">\n</span><span class="s2">  socialStats {</span><span class="se">\n</span><span class="s2">    followerCount</span><span class="se">\n</span><span class="s2">    followingCount</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...userUrl_user</span><span class="se">\n</span><span class="s2">  ...UserProfileMetadataHelmet_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserProfileMetadataHelmet_user on User {</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  twitterScreenName</span><span class="se">\n</span><span class="s2">  navItems {</span><span class="se">\n</span><span class="s2">    title</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SuspendedBannerLoader_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  isSuspended</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useAnalytics_user on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment EntityDrivenSubscriptionLandingPageScreen_writer on User {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  imageId</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  username</span><span class="se">\n</span><span class="s2">  isPartnerProgramEnrolled</span><span class="se">\n</span><span class="s2">  customStyleSheet {</span><span class="se">\n</span><span class="s2">    ...CustomThemeProvider_customStyleSheet</span><span class="se">\n</span><span class="s2">    ...CustomBackgroundWrapper_customStyleSheet</span><span class="se">\n</span><span class="s2">    ...MetaHeader_customStyleSheet</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...MetaHeader_publisher</span><span class="se">\n</span><span class="s2">  ...userUrl_user</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CustomThemeProvider_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...customDefaultBackgroundTheme_customStyleSheet</span><span class="se">\n</span><span class="s2">  ...customStyleSheetFontTheme_customStyleSheet</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment customStyleSheetFontTheme_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  global {</span><span class="se">\n</span><span class="s2">    fonts {</span><span class="se">\n</span><span class="s2">      font1 {</span><span class="se">\n</span><span class="s2">        name</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      font2 {</span><span class="se">\n</span><span class="s2">        name</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      font3 {</span><span class="se">\n</span><span class="s2">        name</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CustomBackgroundWrapper_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  global {</span><span class="se">\n</span><span class="s2">    colorPalette {</span><span class="se">\n</span><span class="s2">      background {</span><span class="se">\n</span><span class="s2">        ...getHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeader_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  header {</span><span class="se">\n</span><span class="s2">    headerScale</span><span class="se">\n</span><span class="s2">    horizontalAlignment</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...MetaHeaderBackground_customStyleSheet</span><span class="se">\n</span><span class="s2">  ...MetaHeaderEngagement_customStyleSheet</span><span class="se">\n</span><span class="s2">  ...MetaHeaderLogo_customStyleSheet</span><span class="se">\n</span><span class="s2">  ...MetaHeaderNavVertical_customStyleSheet</span><span class="se">\n</span><span class="s2">  ...MetaHeaderTagline_customStyleSheet</span><span class="se">\n</span><span class="s2">  ...MetaHeaderThemeProvider_customStyleSheet</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderBackground_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  header {</span><span class="se">\n</span><span class="s2">    headerScale</span><span class="se">\n</span><span class="s2">    backgroundImageDisplayMode</span><span class="se">\n</span><span class="s2">    backgroundImageVerticalAlignment</span><span class="se">\n</span><span class="s2">    backgroundColorDisplayMode</span><span class="se">\n</span><span class="s2">    backgroundColor {</span><span class="se">\n</span><span class="s2">      ...getHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">      ...getOpaqueHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    secondaryBackgroundColor {</span><span class="se">\n</span><span class="s2">      ...getHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    postBackgroundColor {</span><span class="se">\n</span><span class="s2">      ...getHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    backgroundImage {</span><span class="se">\n</span><span class="s2">      ...MetaHeaderBackground_imageMetadata</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderEngagement_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  ...MetaHeaderNav_customStyleSheet</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderNav_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  navigation {</span><span class="se">\n</span><span class="s2">    navItems {</span><span class="se">\n</span><span class="s2">      ...MetaHeaderNav_headerNavigationItem</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderNav_headerNavigationItem on HeaderNavigationItem {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  tagSlugs</span><span class="se">\n</span><span class="s2">  ...MetaHeaderNavLink_headerNavigationItem</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderNavLink_headerNavigationItem on HeaderNavigationItem {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...getNavItemHref_headerNavigationItem</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getNavItemHref_headerNavigationItem on HeaderNavigationItem {</span><span class="se">\n</span><span class="s2">  href</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  tags {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    normalizedTagSlug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderLogo_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  header {</span><span class="se">\n</span><span class="s2">    nameColor {</span><span class="se">\n</span><span class="s2">      ...getHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    nameTreatment</span><span class="se">\n</span><span class="s2">    postNameTreatment</span><span class="se">\n</span><span class="s2">    logoImage {</span><span class="se">\n</span><span class="s2">      ...MetaHeaderLogo_imageMetadata</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    logoScale</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderLogo_imageMetadata on ImageMetadata {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  originalWidth</span><span class="se">\n</span><span class="s2">  originalHeight</span><span class="se">\n</span><span class="s2">  ...PublisherLogo_image</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherLogo_image on ImageMetadata {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  originalHeight</span><span class="se">\n</span><span class="s2">  originalWidth</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderNavVertical_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  navigation {</span><span class="se">\n</span><span class="s2">    navItems {</span><span class="se">\n</span><span class="s2">      ...MetaHeaderNavLink_headerNavigationItem</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...MetaHeaderNav_customStyleSheet</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderTagline_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  header {</span><span class="se">\n</span><span class="s2">    taglineColor {</span><span class="se">\n</span><span class="s2">      ...getHexFromColorValue_colorValue</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    taglineTreatment</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderThemeProvider_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...useMetaHeaderTheme_customStyleSheet</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useMetaHeaderTheme_customStyleSheet on CustomStyleSheet {</span><span class="se">\n</span><span class="s2">  ...customDefaultBackgroundTheme_customStyleSheet</span><span class="se">\n</span><span class="s2">  global {</span><span class="se">\n</span><span class="s2">    colorPalette {</span><span class="se">\n</span><span class="s2">      primary {</span><span class="se">\n</span><span class="s2">        colorPalette {</span><span class="se">\n</span><span class="s2">          tintBackgroundSpectrum {</span><span class="se">\n</span><span class="s2">            ...ThemeUtil_colorSpectrum</span><span class="se">\n</span><span class="s2">            __typename</span><span class="se">\n</span><span class="s2">          }</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  header {</span><span class="se">\n</span><span class="s2">    backgroundColor {</span><span class="se">\n</span><span class="s2">      colorPalette {</span><span class="se">\n</span><span class="s2">        tintBackgroundSpectrum {</span><span class="se">\n</span><span class="s2">          ...ThemeUtil_colorSpectrum</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    postBackgroundColor {</span><span class="se">\n</span><span class="s2">      colorPalette {</span><span class="se">\n</span><span class="s2">        tintBackgroundSpectrum {</span><span class="se">\n</span><span class="s2">          ...ThemeUtil_colorSpectrum</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    backgroundImage {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeader_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...MetaHeaderEngagement_publisher</span><span class="se">\n</span><span class="s2">  ...MetaHeaderLogo_publisher</span><span class="se">\n</span><span class="s2">  ...MetaHeaderNavVertical_publisher</span><span class="se">\n</span><span class="s2">  ...MetaHeaderTagline_publisher</span><span class="se">\n</span><span class="s2">  ...MetaHeaderThemeProvider_publisher</span><span class="se">\n</span><span class="s2">  ...MetaHeaderActions_publisher</span><span class="se">\n</span><span class="s2">  ...MetaHeaderTop_publisher</span><span class="se">\n</span><span class="s2">  ...MetaHeaderNavLink_publisher</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    favicon {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    tagline</span><span class="se">\n</span><span class="s2">    ...CollectionNavigationContextProvider_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    bio</span><span class="se">\n</span><span class="s2">    ...UserProfileCatalogsLink_publisher</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderEngagement_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ...MetaHeaderNav_publisher</span><span class="se">\n</span><span class="s2">  ...PublisherAboutLink_publisher</span><span class="se">\n</span><span class="s2">  ...PublisherFollowButton_publisher</span><span class="se">\n</span><span class="s2">  ...PublisherFollowerCount_publisher</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    creator {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    customStyleSheet {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      ...CustomThemeProvider_customStyleSheet</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...UserProfileCatalogsLink_publisher</span><span class="se">\n</span><span class="s2">    ...UserSubscribeButton_user</span><span class="se">\n</span><span class="s2">    customStyleSheet {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      ...CustomThemeProvider_customStyleSheet</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderNav_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...MetaHeaderNavLink_publisher</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderNavLink_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...getNavItemHref_publisher</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getNavItemHref_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...publisherUrl_publisher</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherAboutLink_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...userUrl_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PublisherFollowButton_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    ...CollectionFollowButton_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...UserFollowButton_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment UserProfileCatalogsLink_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    ...userUrl_user</span><span class="se">\n</span><span class="s2">    homePostsPublished: homepagePostsConnection(paging: {limit: 1}) {</span><span class="se">\n</span><span class="s2">      posts {</span><span class="se">\n</span><span class="s2">        id</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderLogo_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    logo {</span><span class="se">\n</span><span class="s2">      ...MetaHeaderLogo_imageMetadata</span><span class="se">\n</span><span class="s2">      ...PublisherLogo_image</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...auroraHooks_publisher</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderNavVertical_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  ...PublisherAboutLink_publisher</span><span class="se">\n</span><span class="s2">  ...MetaHeaderNav_publisher</span><span class="se">\n</span><span class="s2">  ...MetaHeaderNavLink_publisher</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderTagline_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    tagline</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    bio</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderThemeProvider_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  customStyleSheet {</span><span class="se">\n</span><span class="s2">    ...MetaHeaderThemeProvider_customStyleSheet</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    colorPalette {</span><span class="se">\n</span><span class="s2">      ...customDefaultBackgroundTheme_colorPalette</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderActions_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ...MetaHeaderPubMenu_publisher</span><span class="se">\n</span><span class="s2">  ...SearchWidget_publisher</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    creator {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    customStyleSheet {</span><span class="se">\n</span><span class="s2">      navigation {</span><span class="se">\n</span><span class="s2">        navItems {</span><span class="se">\n</span><span class="s2">          name</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    ...CollectionAvatar_collection</span><span class="se">\n</span><span class="s2">    ...CollectionMetabarActionsPopover_collection</span><span class="se">\n</span><span class="s2">    ...MetaHeaderActions_collection_common</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...UserAvatar_user</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment SearchWidget_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    domain</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...algoliaSearch_publisher</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment algoliaSearch_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CollectionMetabarActionsPopover_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  isAuroraEligible</span><span class="se">\n</span><span class="s2">  isAuroraVisible</span><span class="se">\n</span><span class="s2">  newsletterV3 {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...collectionUrl_collection</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderActions_collection_common on Collection {</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderTop_publisher on Publisher {</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  ... on Collection {</span><span class="se">\n</span><span class="s2">    slug</span><span class="se">\n</span><span class="s2">    ...CollectionMetabarActionsPopover_collection</span><span class="se">\n</span><span class="s2">    ...CollectionAvatar_collection</span><span class="se">\n</span><span class="s2">    ...MetaHeaderTop_collection</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ... on User {</span><span class="se">\n</span><span class="s2">    username</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MetaHeaderTop_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  creator {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CollectionNavigationContextProvider_collection on Collection {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  domain</span><span class="se">\n</span><span class="s2">  slug</span><span class="se">\n</span><span class="s2">  isAuroraVisible</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment useShouldShowEntityDrivenSubscription_creator on User {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n</span><span class="s2">"</span><span class="w">
      </span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">id</code> : アカウントに対応するユーザーID。上記のフォロワー取得エンドポイントで取得可能です。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">homepagePostsFrom</code> : ページネーション用のパラメータで、レスポンス内の <code class="language-plaintext highlighter-rouge">from</code> を参照して全ページのデータを取得できます。</p>
  </li>
</ul>

<p><a href="https://www.postman.com/" target="_blank"><strong>Postman</strong></a> <strong>：</strong></p>

<p><img src="/assets/88f0fb935120/1*dw61NwISVGRbFLlie4Na2w.webp" alt="" loading="lazy" decoding="async" width="1200" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwMjQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/88f0fb935120/1*dw61NwISVGRbFLlie4Na2w.png" /></p>

<p><strong>Response:</strong><br />
<strong>レスポンス：</strong></p>

<p><img src="/assets/88f0fb935120/1*FEt2xWEjJMqpWjxYVUgVWg.webp" alt="" loading="lazy" decoding="async" width="1070" height="998" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDcwIiBoZWlnaHQ9Ijk5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/88f0fb935120/1*FEt2xWEjJMqpWjxYVUgVWg.png" /></p>

<p><code class="language-plaintext highlighter-rouge">response[0]["data"]["userResult"]["homepagePostsConnection"]["posts"]</code> で記事リストの情報を取得できます。</p>

<h4 id="medium-private-api--記事内容の取得">Medium Private API — 記事内容の取得</h4>

<p>次に最も重要な、記事の元の内容を取得します。</p>

<p>Graphql クエリ本文:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"operationName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"PostViewerEdgeContentQuery"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"variables"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"postId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c008a9e8ceca"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"query"</span><span class="p">:</span><span class="w"> </span><span class="s2">"query PostViewerEdgeContentQuery($postId: ID!, $postMeteringOptions: PostMeteringOptions) {</span><span class="se">\n</span><span class="s2">  post(id: $postId) {</span><span class="se">\n</span><span class="s2">    ... on Post {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      viewerEdge {</span><span class="se">\n</span><span class="s2">        id</span><span class="se">\n</span><span class="s2">        fullContent(postMeteringOptions: $postMeteringOptions) {</span><span class="se">\n</span><span class="s2">          isLockedPreviewOnly</span><span class="se">\n</span><span class="s2">          validatedShareKey</span><span class="se">\n</span><span class="s2">          bodyModel {</span><span class="se">\n</span><span class="s2">            ...PostBody_bodyModel</span><span class="se">\n</span><span class="s2">            __typename</span><span class="se">\n</span><span class="s2">          }</span><span class="se">\n</span><span class="s2">          __typename</span><span class="se">\n</span><span class="s2">        }</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostBody_bodyModel on RichText {</span><span class="se">\n</span><span class="s2">  sections {</span><span class="se">\n</span><span class="s2">    name</span><span class="se">\n</span><span class="s2">    startIndex</span><span class="se">\n</span><span class="s2">    textLayout</span><span class="se">\n</span><span class="s2">    imageLayout</span><span class="se">\n</span><span class="s2">    backgroundImage {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      originalHeight</span><span class="se">\n</span><span class="s2">      originalWidth</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    videoLayout</span><span class="se">\n</span><span class="s2">    backgroundVideo {</span><span class="se">\n</span><span class="s2">      videoId</span><span class="se">\n</span><span class="s2">      originalHeight</span><span class="se">\n</span><span class="s2">      originalWidth</span><span class="se">\n</span><span class="s2">      previewImageId</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    ...PostBodySection_paragraph</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...normalizedBodyModel_richText</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostBodySection_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  ...PostBodyParagraph_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostBodyParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  ...ImageParagraph_paragraph</span><span class="se">\n</span><span class="s2">  ...TextParagraph_paragraph</span><span class="se">\n</span><span class="s2">  ...IframeParagraph_paragraph</span><span class="se">\n</span><span class="s2">  ...MixtapeParagraph_paragraph</span><span class="se">\n</span><span class="s2">  ...CodeBlockParagraph_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ImageParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  href</span><span class="se">\n</span><span class="s2">  layout</span><span class="se">\n</span><span class="s2">  metadata {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    originalHeight</span><span class="se">\n</span><span class="s2">    originalWidth</span><span class="se">\n</span><span class="s2">    focusPercentX</span><span class="se">\n</span><span class="s2">    focusPercentY</span><span class="se">\n</span><span class="s2">    alt</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...Markups_paragraph</span><span class="se">\n</span><span class="s2">  ...ParagraphRefsMapContext_paragraph</span><span class="se">\n</span><span class="s2">  ...PostAnnotationsMarker_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment Markups_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  text</span><span class="se">\n</span><span class="s2">  hasDropCap</span><span class="se">\n</span><span class="s2">  dropCapImage {</span><span class="se">\n</span><span class="s2">    ...MarkupNode_data_dropCapImage</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  markups {</span><span class="se">\n</span><span class="s2">    type</span><span class="se">\n</span><span class="s2">    start</span><span class="se">\n</span><span class="s2">    end</span><span class="se">\n</span><span class="s2">    href</span><span class="se">\n</span><span class="s2">    anchorType</span><span class="se">\n</span><span class="s2">    userId</span><span class="se">\n</span><span class="s2">    linkMetadata {</span><span class="se">\n</span><span class="s2">      httpStatus</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MarkupNode_data_dropCapImage on ImageMetadata {</span><span class="se">\n</span><span class="s2">  ...DropCap_image</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment DropCap_image on ImageMetadata {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  originalHeight</span><span class="se">\n</span><span class="s2">  originalWidth</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment ParagraphRefsMapContext_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  text</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostAnnotationsMarker_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  ...PostViewNoteCard_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment PostViewNoteCard_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment TextParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  hasDropCap</span><span class="se">\n</span><span class="s2">  codeBlockMetadata {</span><span class="se">\n</span><span class="s2">    mode</span><span class="se">\n</span><span class="s2">    lang</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...Markups_paragraph</span><span class="se">\n</span><span class="s2">  ...ParagraphRefsMapContext_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment IframeParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  iframe {</span><span class="se">\n</span><span class="s2">    mediaResource {</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      iframeSrc</span><span class="se">\n</span><span class="s2">      iframeHeight</span><span class="se">\n</span><span class="s2">      iframeWidth</span><span class="se">\n</span><span class="s2">      title</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  layout</span><span class="se">\n</span><span class="s2">  ...getEmbedlyCardUrlParams_paragraph</span><span class="se">\n</span><span class="s2">  ...Markups_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getEmbedlyCardUrlParams_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  iframe {</span><span class="se">\n</span><span class="s2">    mediaResource {</span><span class="se">\n</span><span class="s2">      iframeSrc</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment MixtapeParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  mixtapeMetadata {</span><span class="se">\n</span><span class="s2">    href</span><span class="se">\n</span><span class="s2">    mediaResource {</span><span class="se">\n</span><span class="s2">      mediumCatalog {</span><span class="se">\n</span><span class="s2">        id</span><span class="se">\n</span><span class="s2">        __typename</span><span class="se">\n</span><span class="s2">      }</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...GenericMixtapeParagraph_paragraph</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment GenericMixtapeParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  text</span><span class="se">\n</span><span class="s2">  mixtapeMetadata {</span><span class="se">\n</span><span class="s2">    href</span><span class="se">\n</span><span class="s2">    thumbnailImageId</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  markups {</span><span class="se">\n</span><span class="s2">    start</span><span class="se">\n</span><span class="s2">    end</span><span class="se">\n</span><span class="s2">    type</span><span class="se">\n</span><span class="s2">    href</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment CodeBlockParagraph_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  codeBlockMetadata {</span><span class="se">\n</span><span class="s2">    lang</span><span class="se">\n</span><span class="s2">    mode</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment normalizedBodyModel_richText on RichText {</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    markups {</span><span class="se">\n</span><span class="s2">      type</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    codeBlockMetadata {</span><span class="se">\n</span><span class="s2">      lang</span><span class="se">\n</span><span class="s2">      mode</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    ...getParagraphHighlights_paragraph</span><span class="se">\n</span><span class="s2">    ...getParagraphPrivateNotes_paragraph</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  sections {</span><span class="se">\n</span><span class="s2">    startIndex</span><span class="se">\n</span><span class="s2">    ...getSectionEndIndex_section</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...getParagraphStyles_richText</span><span class="se">\n</span><span class="s2">  ...getParagraphSpaces_richText</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getParagraphHighlights_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getParagraphPrivateNotes_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  name</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getSectionEndIndex_section on Section {</span><span class="se">\n</span><span class="s2">  startIndex</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getParagraphStyles_richText on RichText {</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    text</span><span class="se">\n</span><span class="s2">    type</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  sections {</span><span class="se">\n</span><span class="s2">    ...getSectionEndIndex_section</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getParagraphSpaces_richText on RichText {</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    layout</span><span class="se">\n</span><span class="s2">    metadata {</span><span class="se">\n</span><span class="s2">      originalHeight</span><span class="se">\n</span><span class="s2">      originalWidth</span><span class="se">\n</span><span class="s2">      id</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    type</span><span class="se">\n</span><span class="s2">    ...paragraphExtendsImageGrid_paragraph</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  ...getSeriesParagraphTopSpacings_richText</span><span class="se">\n</span><span class="s2">  ...getPostParagraphTopSpacings_richText</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment paragraphExtendsImageGrid_paragraph on Paragraph {</span><span class="se">\n</span><span class="s2">  layout</span><span class="se">\n</span><span class="s2">  type</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">  id</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getSeriesParagraphTopSpacings_richText on RichText {</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    id</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  sections {</span><span class="se">\n</span><span class="s2">    startIndex</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n\n</span><span class="s2">fragment getPostParagraphTopSpacings_richText on RichText {</span><span class="se">\n</span><span class="s2">  paragraphs {</span><span class="se">\n</span><span class="s2">    layout</span><span class="se">\n</span><span class="s2">    text</span><span class="se">\n</span><span class="s2">    codeBlockMetadata {</span><span class="se">\n</span><span class="s2">      lang</span><span class="se">\n</span><span class="s2">      mode</span><span class="se">\n</span><span class="s2">      __typename</span><span class="se">\n</span><span class="s2">    }</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  sections {</span><span class="se">\n</span><span class="s2">    startIndex</span><span class="se">\n</span><span class="s2">    __typename</span><span class="se">\n</span><span class="s2">  }</span><span class="se">\n</span><span class="s2">  __typename</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n</span><span class="s2">"</span><span class="w">
      </span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<ul>
  <li><code class="language-plaintext highlighter-rouge">posdId</code> : 記事のIDで、上で取得した記事一覧のAPIから取得できます。</li>
</ul>

<p><a href="https://www.postman.com/" target="_blank"><strong>Postman</strong></a> <strong>：</strong></p>

<p><img src="/assets/88f0fb935120/1*K7ldG92qvdNIMG89NJC3nw.webp" alt="" loading="lazy" decoding="async" width="1200" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwMjQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/88f0fb935120/1*K7ldG92qvdNIMG89NJC3nw.png" /></p>

<p><strong>Response:</strong><br />
<strong>レスポンス：</strong></p>

<p><img src="/assets/88f0fb935120/1*r3va7Mjc0DTD3pAYkDsozQ.webp" alt="" loading="lazy" decoding="async" width="987" height="1060" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5ODciIGhlaWdodD0iMTA2MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/88f0fb935120/1*r3va7Mjc0DTD3pAYkDsozQ.png" /></p>

<p>文章のソースは上の画像の通りです：</p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">response[0]["data"]["post"]["viewerEdge"]["fullContent"]["bodyModel"]["paragraphs"]</code> : 記事全体の段落で、組み合わせると全文になります。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">["markups"]</code> : 段落の文字スタイル、例えば太字やハイパーリンクなど…</p>
  </li>
</ul>

<blockquote>
  <p><strong><em>この JSON 記述形式を Markdown に変換する方法については、以前開発したオープンソースツール — <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a> — を直接参照または使用してください</em></strong></p>
</blockquote>

<p><a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank"><img src="https://repository-images.githubusercontent.com/493527574/493527574/9b5b7025-cc95-4e81-84a9-b38706093c27" alt="" /></a></p>

<ul>
  <li>自分の有料記事をクロールする場合は、sid と uid のログイントークン情報を付ける必要があります（以下を参照）。</li>
</ul>

<h3 id="medium-x-cloudflare-攻防">Medium x Cloudflare 攻防</h3>

<p>本記事の第二のテーマはCloudflareです。2025年下半期頃から、MediumのCloudflare防御設定がほぼ最高レベルになり、クラウドサービスからのすべてのリクエストがブロックされるようになりました（私はGoogle Apps ScriptやGitHub Actionsで試しましたが、すべてブロックされました）、そのためデータのスクレイピングに失敗しました。</p>

<p><strong>ブロックメッセージ：403</strong></p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;!DOCTYPE html&gt;</span><span class="nt">&lt;html</span> <span class="na">lang=</span><span class="s">"en-US"</span><span class="nt">&gt;&lt;head&gt;&lt;title&gt;</span>少々お待ちください...<span class="nt">&lt;/title&gt;&lt;meta</span> <span class="na">http-equiv=</span><span class="s">"Content-Type"</span> <span class="na">content=</span><span class="s">"text/html; charset=UTF-8"</span><span class="nt">&gt;</span>....
</code></pre></div></div>

<p>これは非常に困りました。なぜなら、私のミラーサイト（<a href="https://zhgchg.li" target="_blank">https://zhgchg.li</a>）は数年間安定して稼働しており、Mediumに新しい記事が公開されると、そこでは定期的にスクリプトが自動実行されて同期される（Private API Graphqlを使って）からです。<strong>もしクラウドサービスがブロックされるなら、私はローカルのパソコンで手動でスクリプトを実行するしかありません</strong>。</p>

<h4 id="header-cookies-に-sid-uid-を追加しない-"><strong>Header Cookies に sid, uid を追加しない ❌</strong></h4>

<p><strong>最初は Header の Cookies に sid や uid を追加して Medium のログイン状態を再現し、問題なく通過できましたが、数ヶ月後にはこの方法も使えなくなりました。</strong></p>

<p><img src="/assets/88f0fb935120/1*nKrcxHJP80VHkDUnQLEFFg.webp" alt="" loading="lazy" decoding="async" width="1200" height="401" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/88f0fb935120/1*nKrcxHJP80VHkDUnQLEFFg.png" /></p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">uid</code> : あなたのユーザーID</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">sid</code> : あなたのアクセストークン <strong>（必ず秘密にしてください）</strong></p>
  </li>
</ul>

<h4 id="cloudflare-worker-リクエストのブリッジ-">Cloudflare Worker リクエストのブリッジ ✅</h4>

<p>いろいろ試しても方法が見つからず、ふと思いついて Cloudflare の魔法で魔法を打ち破りました。Cloudflare を使ったら、意外にも成功しました！Cloudflare の Bot 防護にブロックされませんでした。</p>

<p><strong>デモコード：</strong></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="k">default</span> <span class="p">{</span>

  <span class="k">async</span> <span class="nf">fetch</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">env</span><span class="p">,</span> <span class="nx">ctx</span><span class="p">)</span> <span class="p">{</span>

    <span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">URL</span><span class="p">(</span><span class="nx">request</span><span class="p">.</span><span class="nx">url</span><span class="p">);</span>
    <span class="kd">const</span> <span class="nx">path</span> <span class="o">=</span> <span class="nx">url</span><span class="p">.</span><span class="nx">pathname</span><span class="p">;</span>

    <span class="k">if </span><span class="p">(</span><span class="nx">path</span> <span class="o">==</span> <span class="dl">"</span><span class="s2">/graphql</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
      <span class="kd">let</span> <span class="nx">body</span><span class="p">;</span>
      <span class="k">try</span> <span class="p">{</span>
        <span class="nx">body</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">request</span><span class="p">.</span><span class="nf">json</span><span class="p">();</span>
      <span class="p">}</span> <span class="k">catch</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="dl">"</span><span class="s2">Invalid JSON body</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span> <span class="na">status</span><span class="p">:</span> <span class="mi">400</span> <span class="p">});</span> <span class="c1">// 無効なJSONボディ</span>
      <span class="p">}</span>

      <span class="kd">let</span> <span class="nx">apiURL</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://medium.com/_/graphql</span><span class="dl">"</span><span class="p">;</span>

      <span class="kd">const</span> <span class="nx">apiResponse</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetch</span><span class="p">(</span><span class="nx">apiURL</span><span class="p">,</span> <span class="p">{</span>
        <span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">POST</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
          <span class="dl">"</span><span class="s2">Accept</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span>
          <span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span>
          <span class="dl">"</span><span class="s2">User-Agent</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0</span><span class="dl">"</span><span class="p">,</span>
          <span class="dl">"</span><span class="s2">Cookie</span><span class="dl">"</span><span class="p">:</span> <span class="nx">request</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">"</span><span class="s2">cookie</span><span class="dl">"</span><span class="p">)</span> <span class="c1">// リクエストのCookieを設定</span>
        <span class="p">},</span>
        <span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">body</span><span class="p">),</span>
      <span class="p">});</span>

      <span class="kd">const</span> <span class="nx">json</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">apiResponse</span><span class="p">.</span><span class="nf">json</span><span class="p">();</span>
      <span class="k">return</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">json</span><span class="p">),</span> <span class="p">{</span>
        <span class="na">status</span><span class="p">:</span> <span class="nx">apiResponse</span><span class="p">.</span><span class="nx">status</span><span class="p">,</span>
        <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
          <span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json; charset=utf-8</span><span class="dl">"</span><span class="p">,</span>
        <span class="p">},</span>
      <span class="p">});</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="dl">"</span><span class="s2">Not Found</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span> <span class="na">status</span><span class="p">:</span> <span class="mi">404</span> <span class="p">});</span> <span class="c1">// 見つかりません</span>
  <span class="p">},</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Request:</p>

<p><code class="language-plaintext highlighter-rouge">https://medium.com/_/graphql</code> をあなたがデプロイした Cloudflare Worker の URL に変更するだけです。</p>

<h4 id="まとめ">まとめ</h4>

<p>以上が私がMedium APIと長年戦ってきた軌跡です。現在、すべての記事（Markdownファイル）と画像は <a href="https://zhgchg.li" target="_blank">https://zhgchg.li</a> にバックアップされています。すべての添付画像ファイルも含まれており、GitHubリポジトリとパソコンのハードディスクにもそれぞれ保存しているので、とても安全です。</p>

<blockquote>
  <p>やはり Medium が長く続くことを願っています！本記事の内容は実験参考用であり、著者は一切の使用責任を負いません。</p>
</blockquote>

<p><em><a href="https://zhgchgli.medium.com/medium-private-api-%E8%B3%87%E6%96%99%E7%88%AC%E8%9F%B2%E8%88%87-cloudflare-%E6%94%BB%E9%98%B2%E7%9A%84%E5%BF%83%E8%B7%AF%E6%AD%B7%E7%A8%8B-88f0fb935120" target="_blank">Post</a> Mediumから変換したもの by <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>.</em></p>]]></content>
  </entry><entry>
    <title type="html">App Store Connect API Webhook｜CI/CD自動化ワークフローの効果的連携方法</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/app-store-connect-api-webhook-ci-cd%E8%87%AA%E5%8B%95%E5%8C%96%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%81%AE%E5%8A%B9%E6%9E%9C%E7%9A%84%E9%80%A3%E6%90%BA%E6%96%B9%E6%B3%95-7c0974856393/" rel="alternate" type="text/html" title="App Store Connect API Webhook｜CI/CD自動化ワークフローの効果的連携方法" />
    <published>2025-12-27T17:02:01+08:00</published>
    <updated>2025-12-27T17:05:14+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/7c0974856393</id><summary type="html">iOS開発者向けにApp Store Connect API Webhookを活用したCI/CD自動化手法を解説。Webhook連携で手動作業を削減し、リリース速度を向上させる具体的ステップを紹介します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="iosアプリ開発" /><category term="ci-cd" /><category term="webhook" /><category term="fastlane" /><category term="app-store" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/7c0974856393/1*IqytjX72CmAx9WOx4Rm3gg.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/app-store-connect-api-webhook-ci-cd%E8%87%AA%E5%8B%95%E5%8C%96%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%81%AE%E5%8A%B9%E6%9E%9C%E7%9A%84%E9%80%A3%E6%90%BA%E6%96%B9%E6%B3%95-7c0974856393/"><![CDATA[<h3 id="cicd-app-store-connect-api-webhook-を使った自動化ワークフローの連携">[CI/CD] App Store Connect API Webhook を使った自動化ワークフローの連携</h3>

<p>App Store Connect Webhook の活用事例分析と実際の連携使用ガイド。</p>

<p><img src="/assets/7c0974856393/1*IqytjX72CmAx9WOx4Rm3gg.webp" alt="Photo by Volodymyr Hryshchenko" loading="lazy" decoding="async" width="5472" height="3648" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NDcyIiBoZWlnaHQ9IjM2NDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/7c0974856393/1*IqytjX72CmAx9WOx4Rm3gg.jpeg" /></p>

<p>Photo by <a href="https://unsplash.com/@lunarts?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" target="_blank">Volodymyr Hryshchenko</a></p>

<h4 id="はじめに">はじめに</h4>

<p>Appleは近年、App Store Connect APIを継続的に拡充しており、開発者にとって大きな恩恵となっています。以前は証明書管理も「ハードコア」なWebセッション（有効期限があり、SMS認証コードも必要）に頼らざるを得ず、CI/CDへの統合が非常に難しかったです。また、ストアのレビューも不安定なRSSに依存するしかありませんでした。</p>

<p>ここ数年、ほぼ毎年新機能が追加されており、開発、テストからデプロイのプロセスだけでなく、後期の評価、財務、データレポートまで段階的にネイティブサポートされています。さらに、ユーザー管理、グループ、TestFlightなどの機能も強化され、<strong>App Store Connect API が Apple 開発者の開発体験をより良く向上させることができる</strong>ようになりました。</p>

<blockquote>
  <p><em>関連記事：「 <a href="/posts/zrealm-dev/app-store-connect-api-customer-reviews-管理を強化-in-app-purchases-subscriptionsも対応-f1365e51902c/">App Store Connect API がカスタマーレビューの読み取りと管理をサポート開始</a> 」</em></p>
</blockquote>

<h4 id="wwdc-2025-app-store-connect-apiで開発プロセスを自動化する"><a href="https://developer.apple.com/videos/play/wwdc2025/324/" target="_blank">WWDC 2025 App Store Connect APIで開発プロセスを自動化する</a></h4>

<p><a href="https://developer.apple.com/videos/play/wwdc2025/324/" target="_blank"><img src="https://devimages-cdn.apple.com/wwdc-services/images/3055294D-836B-4513-B7B0-0BC5666246B0/9859/9859_wide_250x141_2x.jpg" alt="" /></a></p>

<p><strong>2025 WWDCでは待望の新機能 — Webhook通知が登場：</strong></p>

<ul>
  <li>
    <p><strong>ビルドアップロードのステータス (<a href="https://developer.apple.com/help/app-store-connect/reference/app-uploads/build-upload-statuses" target="_blank">ビルドアップロードのステータス</a> が変更されます)</strong><br />
ビルドアップロードのステータスが変更されたときに関連情報を受け取ります。<br />
<code class="language-plaintext highlighter-rouge">Complete / Failed / Processing</code></p>
  </li>
  <li>
    <p><strong>App バージョンのステータス (<a href="https://developer.apple.com/help/app-store-connect/reference/app-information/app-and-submission-statuses#app-statuses" target="_blank">アプリバージョンのステータス</a> の変更)</strong><br />
App バージョンのステータスが変更されたときに関連情報を受け取ります。<br />
<code class="language-plaintext highlighter-rouge">Prepare for Submission / Ready for Review / Waiting for Review / Ready for Distribution / Rejected…</code></p>
  </li>
  <li>
    <p><strong>TestFlight バージョン状態 (新しい<a href="https://developer.apple.com/help/app-store-connect/test-a-beta-version/view-tester-feedback" target="_blank">TestFlightフィードバック</a> がテスターから送信されました)</strong><br />
テスターがフィードバック（クラッシュレポートやスクリーンショット）を送信した際に関連情報を受け取ります。</p>
  </li>
  <li>
    <p><strong>Apple-hosted のリソースパックの状態変更 (<a href="https://developer.apple.com/help/app-store-connect/reference/app-uploads/apple-hosted-asset-pack-statuses" target="_blank">Apple-hostedアセットパックバージョンのステータス</a> が変更されます)</strong><br />
Appleがホストするアセットパックのバージョンに特定の変更があった際に関連情報を受け取ります。</p>
  </li>
</ul>

<h4 id="app-store-connect-api--webhook通知-"><a href="https://developer.apple.com/documentation/AppStoreConnectAPI/webhook-notifications" target="_blank">App Store Connect API / Webhook通知</a> :</h4>

<blockquote>
  <p><em>Webhookは、あるシステムがリアルタイムでデータを別のシステムにウェブ経由で送信することを可能にします。</em></p>
</blockquote>

<blockquote>
  <p><em>Webhookは、あるシステムがネットワークを介してリアルタイムにデータを別のシステムに送信する仕組みです。</em></p>
</blockquote>

<blockquote>
  <p><em>従来のAPIとは異なり、データを受け取る際に一方のシステムがリクエストを送る必要はなく、Webhookはイベント発生時に即座にデータを受け取るシステムへプッシュできます。</em></p>
</blockquote>

<blockquote>
  <p><em>従来のAPIとは異なり、従来のAPIはデータを受け取る側が能動的にリクエストを送る必要がありますが、Webhookはイベント発生時に即座にデータを受け取る側へプッシュします。</em></p>
</blockquote>

<blockquote>
  <p><em>Webhookはイベント駆動型で、特定のアクションやイベントによりトリガーされ、関連データを事前に設定されたURL（「webhook URL」または「callback URL」とも呼ばれます）に即時送信します。</em></p>
</blockquote>

<blockquote>
  <p><em>Webhookはイベント駆動型で、特定のアクションやイベントが発生したときに、関連データをあらかじめ設定したURL（「Webhook URL」または「Callback URL」とも呼ばれる）に即時に送信します。</em></p>
</blockquote>

<blockquote>
  <p><em>通知Webhookは、サーバー上に作成するエンドポイントです。</em></p>
</blockquote>

<blockquote>
  <p><em>通知型Webhookは、自分のサーバー上に作成したエンドポイント（endpoint）です。</em></p>
</blockquote>

<blockquote>
  <p><em>このWebhookエンドポイントはApp Store ConnectからのHTTP POSTリクエストを受信します。</em></p>
</blockquote>

<blockquote>
  <p><em>このWebhookエンドポイントはApp Store ConnectからのHTTP POSTリクエストを受信します。</em></p>
</blockquote>

<blockquote>
  <p><em>POSTリクエストは、あなたのアプリに関する重要なイベントを通知します。</em></p>
</blockquote>

<blockquote>
  <p><em>これらの POST リクエストは、あなたのアプリに関連する重要なイベントを説明します。</em></p>
</blockquote>

<blockquote>
  <p><em>Webhook通知エンドポイントを使って、アプリで発生するイベントの通知を設定します。</em></p>
</blockquote>

<blockquote>
  <p><em>Webhook通知エンドポイントを使用して、アプリで発生するさまざまなイベントの通知を受け取るように設定できます。</em></p>
</blockquote>

<h3 id="5つの活用事例">5つの活用事例</h3>

<h4 id="1-ビルド処理完了後に審査申請をトリガーする">1. ビルド処理完了後に審査申請をトリガーする</h4>

<p><strong>以前：</strong></p>

<p><img src="/assets/7c0974856393/1*usYZtMkzAu-bA4fVX8ZbUQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="465" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQ2NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/7c0974856393/1*usYZtMkzAu-bA4fVX8ZbUQ.png" /></p>

<p>従来、AppのCI/CDパッケージ送信時には、パッケージアップロード後に<strong>Appleの処理完了を待つ必要があり</strong>、その後に審査申請を続けていました。Fastlaneのデフォルトの方法は、App Store Connectをポーリングしてアップロードしたビルドの状態を確認し、Completeになるまで審査申請のLaneを実行しません。</p>

<blockquote>
  <p><strong><em>待ち時間は約20分</em></strong> <em>です。Self-hosted CI/CDなら問題ありませんが、クラウドサービスを利用している場合、この20分の待機時間は非常にリソースの無駄になります。例えばGitHub Runner macOSでは1分あたり0.062米ドルなので、<strong>審査待ちだけで毎回1.24米ドルの無駄なコストが発生します。</strong></em></p>
</blockquote>

<p><img src="/assets/7c0974856393/1*2-Zn2ApgVYd5S5KzxMLEMQ.webp" alt="Ref: Build Completed Processing 通知信 搭配 Gmail Filter + Google Apps Script" loading="lazy" decoding="async" width="694" height="340" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2OTQiIGhlaWdodD0iMzQwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/7c0974856393/1*2-Zn2ApgVYd5S5KzxMLEMQ.png" /></p>

<p>Ref: <a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-scriptでgmailをslackに自動転送-フィルター連携で効率化-d414bdbdb8c9/">Build Completed Processing 通知信 搭配 Gmail Filter + Google Apps Script</a></p>

<p>Webhookでの自動通知がなかった時代には、「<a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-scriptでgmailをslackに自動転送-フィルター連携で効率化-d414bdbdb8c9/">Build Completed Processing 通知メールをGmailフィルターとGoogle Apps Scriptでトリガーする</a>」という方法を使っていましたが、少しハードコアな手順でした。</p>

<p><strong>After:</strong></p>

<p><img src="/assets/7c0974856393/1*ADkNoScFn4M_dIgv3sAKaw.webp" alt="" loading="lazy" decoding="async" width="1200" height="301" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjMwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/7c0974856393/1*ADkNoScFn4M_dIgv3sAKaw.png" /></p>

<ul>
  <li>
    <p>Webhookがあれば、ビルドのアップロード完了時点で処理を終了できます。</p>
  </li>
  <li>
    <p><strong>App Store Connectのビルドプロセス完了後にWebhook通知が送信され、通知を受け取った後に審査申請のステップを続行します。</strong></p>
  </li>
  <li>
    <p><strong>待ち時間ゼロのコスト</strong></p>
  </li>
</ul>

<h4 id="2-gitflow-release-フローと-app-リリースのタイミングの同期">2. GitFlow Release フローと App リリースのタイミングの同期</h4>

<p><strong>以前：</strong></p>

<blockquote>
  <p><em>GitFlowの最終リリース時には、developブランチをmasterブランチにマージする必要があります。masterブランチは現在の本番バージョンを表しています。</em></p>
</blockquote>

<p>これまでは定期的に手動または自動で実行していました。例えば、月曜日の午後にAppをリリースし、月曜日に決まってdevelopからmasterへマージするなどです。手動実行は面倒で、自動実行の場合は延期したらどうする？月曜日がちょうど休日だったら？実際にはAppがリリースされていないのに、先にdevelopをmasterにマージしてしまう問題がありました。</p>

<p>ほとんどの場合は重要ではありませんが、例えばこの期間中にホットフィックスを挟むような極端な状況では差異が生じる可能性があります。しかし、完全で安定したCI/CD開発プロセスを追求する場合、これは検討に値するケースです。</p>

<p><strong>別の方法として、「<a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-scriptでgmailをslackに自動転送-フィルター連携で効率化-d414bdbdb8c9/">App is Ready for Sale 通知メールをGmailフィルターとGoogle Apps Scriptでトリガーする</a>」も可能です。</strong></p>

<p><strong>After:</strong></p>

<p><img src="/assets/7c0974856393/1*6JjHC6GKc4fKXrh-WWCJVA.webp" alt="" loading="lazy" decoding="async" width="1200" height="224" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjIyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/7c0974856393/1*6JjHC6GKc4fKXrh-WWCJVA.png" /></p>

<ul>
  <li>
    <p>Webhookがあれば、Appの公開通知を受け取った後に直接CI/CDアクション（MasterからDevelopへ）をトリガーできます。</p>
  </li>
  <li>
    <p>Appが本当にリリースされたことを確認してからMasterに戻すことができます。</p>
  </li>
</ul>

<h4 id="3-アプリリリースメッセージ">3. アプリリリースメッセージ</h4>

<blockquote>
  <p><em>アプリがリリースされユーザーに公開された後、もう一つよくある内部ワークフローとして、関連チームへの通知、バージョンに含まれるタスクの共有、関連タスクの完了があります。</em></p>
</blockquote>

<p><strong>以前：</strong></p>

<p>同様に、手動または定期的な自動実行、またはメールを使って <a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-scriptでgmailをslackに自動転送-フィルター連携で効率化-d414bdbdb8c9/"><strong>Gmailフィルター＋Google Apps Scriptでトリガーする</strong></a> 。</p>

<p><strong>After:</strong></p>

<p><img src="/assets/7c0974856393/1*UuGPKonNhXRUMZ71rDQcdw.webp" alt="" loading="lazy" decoding="async" width="1200" height="443" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQ0MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/7c0974856393/1*UuGPKonNhXRUMZ71rDQcdw.png" /></p>

<ul>
  <li>Webhook を使うことで、App の公開通知を受け取った後に Jira や Asana の API と連携し、該当バージョンのチケットを一括で完了にし、完了したタスクのリリースメッセージを Slack に投稿できます。</li>
</ul>

<h4 id="4-ビルド失敗--レビュー却下通知機能">4. ビルド失敗 / レビュー却下通知機能</h4>

<blockquote>
  <p><em>前述の1、2で、以前はメール通知を通じてワークフローをトリガーすることが可能でしたが、大規模なチームで権限管理が厳しい組織では、<strong>iOS開発者は「開発者」バックエンド権限のみを持ち、リリースやApp管理ができないため、Appの状態変更に関するメール通知を受け取ることができません。これにはアップロードしたビルドの拒否や審査拒否の通知メールも含まれます。</strong></em></p>
</blockquote>

<p><strong>以前：</strong></p>

<p>以前は親切な人（別名PM）がメールをエンジニアに転送するしかなく、親切な人も気づかなければ、リリース直前になってAppが拒否されていることに気づくことがありました！</p>

<p><strong>After:</strong></p>

<p><img src="/assets/7c0974856393/1*unKq9zdc8tJEqlNmfXiRYA.webp" alt="" loading="lazy" decoding="async" width="1200" height="582" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU4MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/7c0974856393/1*unKq9zdc8tJEqlNmfXiRYA.png" /></p>

<ul>
  <li>このケースは比較的シンプルで、Webhook通知を受け取った後、メッセージをSlackに転送します。</li>
</ul>

<h4 id="5-testflight-フィードバック通知機能">5. Testflight フィードバック通知機能</h4>

<blockquote>
  <p><em>4に似ていますが、TestFlightフィードバックWebhook通知に切り替えただけです。</em></p>
</blockquote>

<p><strong>以前：</strong></p>

<p>従来、開発者は自分で App Store Connect の TestFlight 管理画面にアクセスしてテスターのフィードバックやクラッシュ問題を確認するしかなく、<strong>非常に見落としやすかった（1年前に報告された提案が1年後にようやく発見されたこともある）</strong>。</p>

<p><strong>After:</strong></p>

<ul>
  <li>Testflight Feedback Webhook 通知を受け取った後、メッセージを Slack に転送する。</li>
</ul>

<p>— — —</p>

<blockquote>
  <p><em>その他の活用方法も自由にアイデアを出してください。次に接続方法を紹介します。</em></p>
</blockquote>

<h3 id="app-store-connect-api-webhook-設定">App Store Connect API Webhook 設定</h3>

<blockquote>
  <p><em>権限要件：<strong>Admin または Account Holder の権限が必要です</strong>。</em></p>
</blockquote>

<h4 id="app-store-connect-api-webhook-通知の作成">App Store Connect API Webhook 通知の作成</h4>

<ol>
  <li>
    <p><a href="https://appstoreconnect.apple.com/access/users" target="_blank">App Store Connect 管理画面へ移動</a></p>
  </li>
  <li>
    <p>「ユーザーとアクセス権限 (Users and Access)」 -&gt; 「統合 (Integrations)」に移動してください。</p>
  </li>
  <li>
    <p>「その他の統合 (Additional)」の下にある「Webhooks」をクリックしてください。</p>
  </li>
  <li>
    <p>「Webhookを作成」ボタンをクリックしてください。</p>
  </li>
</ol>

<p><img src="/assets/7c0974856393/1*e_6oin7tJjAB2gXl3txJow.webp" alt="" loading="lazy" decoding="async" width="716" height="767" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MTYiIGhlaWdodD0iNzY3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/7c0974856393/1*e_6oin7tJjAB2gXl3txJow.jpeg" /></p>

<ul>
  <li>
    <p>名称：Webhookの名前を入力してください</p>
  </li>
  <li>
    <p>承載 URL(Payload URL)：Webhook通知を受け取るサービスのURLを入力してください</p>
  </li>
  <li>
    <p>密钥(Secret) 文字列：Webhookリクエスト検証用の秘密鍵（<a href="https://www.random.org/strings/?num=1&amp;len=32&amp;digits=on&amp;upperalpha=on&amp;loweralpha=on&amp;unique=on&amp;format=html&amp;rnd=new" target="_blank">ランダムな文字列を生成</a>して使用可能）</p>
  </li>
  <li>
    <p>App：Webhook通知を受け取る対象のAppを選択してください</p>
  </li>
  <li>
    <p><strong>トリガーイベント：</strong></p>
  </li>
</ul>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">TestFlight</span> <span class="nt">フィードバック</span>
<span class="nt">テスターがフィードバックを残したときに関連情報を受け取ります</span><span class="err">。</span>
<span class="o">[]</span> <span class="nt">クラッシュフィードバック</span>
<span class="o">[]</span> <span class="nt">スクリーンショットフィードバック</span>

<span class="o">[]</span> <span class="nt">TestFlight</span> <span class="nt">バージョンステータス</span>
<span class="nt">TestFlight</span> <span class="nt">バージョンステータスが変更されたときに関連情報を受け取ります</span><span class="err">。</span><span class="nt">詳細はこちら</span>

<span class="o">[]</span> <span class="nt">App</span> <span class="nt">バージョンステータス</span>
<span class="nt">App</span> <span class="nt">バージョンステータスが変更されたときに関連情報を受け取ります</span><span class="err">。</span><span class="nt">詳細はこちら</span>

<span class="o">[]</span> <span class="nt">ビルドアップロードステータス</span>
<span class="nt">ビルドアップロードステータスが変更されたときに関連情報を受け取ります</span><span class="err">。</span><span class="nt">詳細はこちら</span>

<span class="nt">背景素材</span>
<span class="nt">Apple</span> <span class="nt">がホストするアセットパッケージのバージョンに特定の変更があったときに関連情報を受け取ります</span><span class="err">。</span><span class="nt">詳細はこちら</span>

<span class="o">[]</span> <span class="nt">App</span> <span class="nt">Store</span> <span class="nt">公開バージョンを更新</span>
<span class="o">[]</span> <span class="nt">外部</span> <span class="nt">TestFlight</span> <span class="nt">公開バージョンを更新</span>
<span class="o">[]</span> <span class="nt">内部</span> <span class="nt">TestFlight</span> <span class="nt">公開バージョンを作成</span>
<span class="o">[]</span> <span class="nt">アセットパッケージバージョンを更新</span>
</code></pre></div></div>

<p>必要に応じて項目を選択することも、すべて選択して通知を受け取った後に処理の要否を判断することもできます。</p>

<p><strong>最後に「追加」をクリックしてWebhookを作成します。</strong></p>

<h4 id="app-store-connect-api-webhook-通知のテスト">App Store Connect API Webhook 通知のテスト</h4>

<p>Webhook ページに入る。</p>

<p><img src="/assets/7c0974856393/1*-pEVZ24cpSPBabtzMwll4Q.webp" alt="" loading="lazy" decoding="async" width="979" height="548" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NzkiIGhlaWdodD0iNTQ4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/7c0974856393/1*-pEVZ24cpSPBabtzMwll4Q.png" /></p>

<p>右上の「テスト」をクリックしてテスト通知を受け取ります。</p>

<p><strong>テスト通知内容は以下の通りです：</strong></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">Headers:</span><span class="w">
</span><span class="p">{</span><span class="w">
  </span><span class="nl">"content-type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"application/json"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"x-apple-jingle-correlation-key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"PNSCHDQW3MY2AX6VSRFHYYNUL4"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"x-apple-request-uuid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"7b64238e-16db-31a0-5fd5-944a7c61b45f"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"x-apple-signature"</span><span class="p">:</span><span class="w"> </span><span class="s2">"hmacsha256=cf50020f0bbd3c5274860594f616f1806965c1f9fb765d8d278f512dff5b4c0e"</span><span class="p">,</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="err">Body:</span><span class="w">
</span><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"webhookPingCreated"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"65726e27-cb79-47f2-a3e4-c8ced9f356e8"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"version"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"timestamp"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-26T15:47:38.472168681Z"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h4 id="app-store-connect-api-webhook-通知送信履歴">App Store Connect API Webhook 通知送信履歴</h4>

<p>Webhook ページ下部の「最近の送信項目」には、最近送信された Webhook イベントが表示されます。</p>

<p><img src="/assets/7c0974856393/1*lacj5lpaDwJtN0hgA5EAVg.webp" alt="" loading="lazy" decoding="async" width="1200" height="502" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjUwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/7c0974856393/1*lacj5lpaDwJtN0hgA5EAVg.png" /></p>

<h4 id="app-store-connect-api-webhook-通知の検証">App Store Connect API Webhook 通知の検証</h4>

<p>Webhook を作成する際に「シークレット文字列」を入力します。リクエストの検証を推奨しており、この Webhook URL の漏洩を防ぎ、悪意のある第三者が自由に偽造して Webhook イベントをあなたのサービスに送信するのを防ぎます。</p>

<p><strong>認証方法：</strong></p>

<blockquote>
  <p><em>Request Body に対して設定したキー文字列で HMAC-SHA256 を計算し、HEX 形式の文字列を出力します。この文字列と Request Headers の <code class="language-plaintext highlighter-rouge">x-apple-signature</code> にある <code class="language-plaintext highlighter-rouge">hmacsha256=</code> の後の文字列を比較します。</em></p>
</blockquote>

<p><strong>実装方法 — Nodejs:</strong></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">crypto</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">crypto</span><span class="dl">'</span><span class="p">;</span>

<span class="kd">function</span> <span class="nf">verifyAppleWebhook</span><span class="p">(</span><span class="nx">rawBody</span><span class="p">,</span> <span class="nx">appleSignature</span><span class="p">,</span> <span class="nx">secret</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">hex</span> <span class="o">=</span> <span class="nx">crypto</span>
    <span class="p">.</span><span class="nf">createHmac</span><span class="p">(</span><span class="dl">'</span><span class="s1">sha256</span><span class="dl">'</span><span class="p">,</span> <span class="nx">secret</span><span class="p">)</span>
    <span class="p">.</span><span class="nf">update</span><span class="p">(</span><span class="nx">rawBody</span><span class="p">,</span> <span class="dl">'</span><span class="s1">utf8</span><span class="dl">'</span><span class="p">)</span>
    <span class="p">.</span><span class="nf">digest</span><span class="p">(</span><span class="dl">'</span><span class="s1">hex</span><span class="dl">'</span><span class="p">);</span>

  <span class="k">return</span> <span class="s2">`hmacsha256=</span><span class="p">${</span><span class="nx">hex</span><span class="p">}</span><span class="s2">`</span> <span class="o">===</span> <span class="nx">appleSignature</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><strong>実現方法 — Cloudflare Worker:</strong></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">bufferToHex</span><span class="p">(</span><span class="nx">buffer</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="p">[...</span><span class="k">new</span> <span class="nc">Uint8Array</span><span class="p">(</span><span class="nx">buffer</span><span class="p">)]</span>
    <span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="nx">b</span> <span class="o">=&gt;</span> <span class="nx">b</span><span class="p">.</span><span class="nf">toString</span><span class="p">(</span><span class="mi">16</span><span class="p">).</span><span class="nf">padStart</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="dl">'</span><span class="s1">0</span><span class="dl">'</span><span class="p">))</span>
    <span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="dl">''</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">hmacSha256Hex</span><span class="p">(</span><span class="nx">secret</span><span class="p">,</span> <span class="nx">message</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">enc</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">TextEncoder</span><span class="p">();</span>

  <span class="kd">const</span> <span class="nx">key</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">crypto</span><span class="p">.</span><span class="nx">subtle</span><span class="p">.</span><span class="nf">importKey</span><span class="p">(</span>
    <span class="dl">'</span><span class="s1">raw</span><span class="dl">'</span><span class="p">,</span>
    <span class="nx">enc</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="nx">secret</span><span class="p">),</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">HMAC</span><span class="dl">'</span><span class="p">,</span> <span class="na">hash</span><span class="p">:</span> <span class="dl">'</span><span class="s1">SHA-256</span><span class="dl">'</span> <span class="p">},</span>
    <span class="kc">false</span><span class="p">,</span>
    <span class="p">[</span><span class="dl">'</span><span class="s1">sign</span><span class="dl">'</span><span class="p">]</span>
  <span class="p">);</span>

  <span class="kd">const</span> <span class="nx">signature</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">crypto</span><span class="p">.</span><span class="nx">subtle</span><span class="p">.</span><span class="nf">sign</span><span class="p">(</span>
    <span class="dl">'</span><span class="s1">HMAC</span><span class="dl">'</span><span class="p">,</span>
    <span class="nx">key</span><span class="p">,</span>
    <span class="nx">enc</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span>
  <span class="p">);</span>

  <span class="k">return</span> <span class="nf">bufferToHex</span><span class="p">(</span><span class="nx">signature</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">verifyAppleWebhook</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">secret</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">appleSignature</span> <span class="o">=</span> <span class="nx">request</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">X-Apple-Signature</span><span class="dl">'</span><span class="p">);</span>

  <span class="kd">const</span> <span class="nx">rawBody</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">request</span><span class="p">.</span><span class="nf">clone</span><span class="p">().</span><span class="nf">text</span><span class="p">();</span>
  <span class="kd">const</span> <span class="nx">calculated</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">hmacSha256Hex</span><span class="p">(</span><span class="nx">secret</span><span class="p">,</span> <span class="nx">rawBody</span><span class="p">);</span>

  <span class="k">return</span> <span class="dl">"</span><span class="s2">hmacsha256=</span><span class="dl">"</span><span class="o">+</span><span class="nx">calculated</span> <span class="o">===</span> <span class="nx">appleSignature</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<ul>
  <li>Cloudflare Worker には crypto モジュールがないため、Web Crypto API（crypto.subtle）を使用する必要があります。</li>
</ul>

<p><strong>実装方法 — Google Apps Script Web App ❌</strong></p>

<p>技術的な制限により、Google Apps Script Web App の <code class="language-plaintext highlighter-rouge">doGet(e)/doPost(e)</code> ではリクエストヘッダーを取得できないため、この方法でリクエスト元の検証はできません。</p>

<p>URLクエリにキーとなるパラメータを追加して、簡単な判定保護を行うことが最大限です。</p>

<h3 id="app-store-connect-api-webhook-通知-payload">App Store Connect API Webhook 通知 Payload</h3>

<p>こちらでは、Appのアップロードや審査申請の過程で受け取るイベントPayloadをいくつか集めました。自動化開発の際に参考にしてください。</p>

<blockquote>
  <p><em>Webhook はイベントとステータス名のみを送信し、バージョン番号や審査拒否理由などの詳細情報は含まれません。<strong>完全な情報を取得するには、Event Payload 内の Relationships Link を使って自分で App Store Connect API を呼び出す必要があります。</strong></em></p>
</blockquote>

<h4 id="ビルドバージョンアップロード--プロセス完了">ビルドバージョンアップロード — プロセス完了</h4>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"buildUploadStateUpdated"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"version"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"oldState"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"PROCESSING"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"newState"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"COMPLETE"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"instance"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"buildUploads"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"links"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/buildUploads/xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h4 id="ビルドバージョンアップロード--処理失敗">ビルドバージョンアップロード — 処理失敗</h4>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"buildUploadStateUpdated"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"oldState"</span><span class="p">:</span><span class="w"> </span><span class="s2">"PROCESSING"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"newState"</span><span class="p">:</span><span class="w"> </span><span class="s2">"FAILED"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"instance"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"buildUploads"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/buildUploads/xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>ほとんどの場合、バイナリが拒否されます。例えば、マイクを使用しているのに宣言していないなどです。</p>

<h4 id="app-バージョンの状態--prepare-for-submission提出準備中">App バージョンの状態 — Prepare For Submission（提出準備中）</h4>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersionAppVersionStateUpdated"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"version"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"newValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"PREPARE_FOR_SUBMISSION"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"oldValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"DEVELOPER_REJECTED"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"timestamp"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-18T05:01:47.118Z"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"instance"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersions"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"links"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>新しいバージョン番号が作成され、審査のために提出する準備ができた段階で、バージョン情報や更新内容を入力し、審査に提出するビルドを選択できます。</p>

<h4 id="app-バージョンのステータス--ready-for-review審査準備完了"><strong>App バージョンのステータス — Ready For Review（審査準備完了）</strong></h4>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersionAppVersionStateUpdated"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"version"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"newValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"READY_FOR_REVIEW"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"oldValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"PREPARE_FOR_SUBMISSION"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"timestamp"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-18T03:41:12.516Z"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"instance"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersions"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"links"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>審査用の資料が確定し、審査準備が整ったとき。</p>

<h4 id="app-バージョンの状態--waiting-for-review審査待ち">App バージョンの状態 — Waiting For Review（審査待ち）</h4>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersionAppVersionStateUpdated"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"version"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"newValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"WAITING_FOR_REVIEW"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"oldValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"READY_FOR_REVIEW"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"timestamp"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-18T03:41:21.179Z"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"instance"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersions"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"links"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Appは審査提出が完了し、現在審査待ちの状態です。</p>

<h4 id="app-バージョンの状態--developer-rejected開発者による拒否">App バージョンの状態 — Developer Rejected（開発者による拒否）</h4>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersionAppVersionStateUpdated"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"version"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"newValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"DEVELOPER_REJECTED"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"oldValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"WAITING_FOR_REVIEW"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"timestamp"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-18T03:50:30.552Z"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"instance"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersions"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"links"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>開発者が審査中のバージョンを取り下げる。</p>

<h4 id="app-バージョンのステータス--審査中公式による審査中">App バージョンのステータス — 審査中（公式による審査中）</h4>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersionAppVersionStateUpdated"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"version"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"newValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"IN_REVIEW"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"oldValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"WAITING_FOR_REVIEW"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"timestamp"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-18T22:05:50.038Z"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"instance"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersions"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"links"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h4 id="app-バージョンの状態--pending-developer-release審査完了リリース待ち">App バージョンの状態 — Pending Developer Release（審査完了、リリース待ち）</h4>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersionAppVersionStateUpdated"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"version"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"newValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"PENDING_DEVELOPER_RELEASE"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"oldValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"IN_REVIEW"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"timestamp"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-18T22:34:18.785Z"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"instance"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersions"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"links"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<blockquote>
  <p><em>Pending Developer Release イベントの時間から Waiting For Review イベントの時間を引くと、Appが審査提出からリリース可能な状態になるまでの待機時間になります。</em></p>
</blockquote>

<h4 id="app-バージョンの状態--ready-for-distribution-アプリ配信準備完了-別名-ready-for-sale">App バージョンの状態 — Ready for Distribution (アプリ配信準備完了) 別名 Ready For Sale</h4>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersionAppVersionStateUpdated"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"version"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"newValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"READY_FOR_DISTRIBUTION"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"oldValue"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"PENDING_DEVELOPER_RELEASE"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"timestamp"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-23T06:03:50.925Z"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"instance"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"data"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"type"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersions"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"id"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="nl">"links"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xx-xx-xx-xxx"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>App はリリース準備完了（ほぼ Ready For Sale と同義で、Ready For Sale のイベントはありません）。</p>

<blockquote>
  <p><em>あなたのアプリは承認され、配布の準備が整いました。</em></p>
</blockquote>

<blockquote>
  <p><em>アプリを配布するには、<a href="https://developer.apple.com/help/app-store-connect/manage-agreements/view-agreements-status" target="_blank">契約</a>が有効である必要があります。アカウント所有者は、ビジネスセクションで最新の契約を承認できます。</em></p>
</blockquote>

<h3 id="app-store-connect-api-webhook-ワークフロー連携">App Store Connect API Webhook ワークフロー連携</h3>

<h4 id="方法-1--fastlaneを使ってapp-store-connect-apiに接続する">方法 1 — Fastlaneを使ってApp Store Connect APIに接続する</h4>

<p>こちらで最も速い方法は、直接CI/CDサービスでトリガーし、Fastlaneに内蔵されているSpaceshipを使ってApp Store Connect APIと連携することです。</p>

<blockquote>
  <p><em>もし元々 <a href="https://docs.fastlane.tools/app-store-connect-api/" target="_blank">Fastlane で App Store Connect API</a> を使って Match 証明書や審査提出を管理している場合、この方法はそのまま無痛で利用できます。使っていない場合は、まず <a href="https://docs.fastlane.tools/app-store-connect-api/" target="_blank">公式ドキュメント</a> を参考にして API キーを作成し、CI/CD サービスのシークレットに安全に保存してください。</em></p>
</blockquote>

<p><img src="/assets/7c0974856393/1*FrJoXtV2lrk09KnAt2Hydg.webp" alt="" loading="lazy" decoding="async" width="2141" height="577" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMTQxIiBoZWlnaHQ9IjU3NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/7c0974856393/1*FrJoXtV2lrk09KnAt2Hydg.png" /></p>

<ul>
  <li><strong>App Store Connect</strong></li>
</ul>

<ol>
  <li>
    <p>Appの状態が変わったとき</p>
  </li>
  <li>
    <p>Webhookをトリガーする</p>
  </li>
</ol>

<ul>
  <li><strong>Webhook Endpoint</strong><br />
<code class="language-plaintext highlighter-rouge">自社サービス/API または シンプルな FAAS サービス（Cloudflare Worker / AWS Lambda / Cloud Functions / Google Apps Script）でも構いません</code></li>
</ul>

<ol>
  <li>
    <p>Webhook の検証（オプション）</p>
  </li>
  <li>
    <p>Webhook イベントの処理およびイベントリクエストを CI/CD サービスに転送して実行<br />
<code class="language-plaintext highlighter-rouge">例：GitHub API を使って GitHub Actions をトリガーする..</code></p>
  </li>
</ol>

<ul>
  <li><strong>CI/CDサービス</strong><br />
<code class="language-plaintext highlighter-rouge">GitHub Actions / Bitbucket Pipeline / Gitlab Runner…</code></li>
</ul>

<ol>
  <li>
    <p>アクションをトリガーする</p>
  </li>
  <li>
    <p>Fastlane スクリプトを実行し、Fastlane Spaceship 認証を再利用する</p>
  </li>
</ol>

<ul>
  <li><strong>App Store Connect</strong></li>
</ul>

<ol>
  <li>App Store Connect API で完全な情報を取得する</li>
</ol>

<ul>
  <li><strong>CI/CDサービス</strong></li>
</ul>

<ol>
  <li>続くステップ、例えば通知の送信や別のアクションのトリガー</li>
</ol>

<p><strong>Fastlaneの例:</strong></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="c1"># 使用方法:</span>
  <span class="c1">#   bundle exec fastlane appStoreConnectWebhookHandler \</span>
  <span class="c1">#     data:'{"data":{"type":"buildUploadStateUpdated","id":"xxx-xxx-xxx-xx-xxx","version":1,"attributes":{"oldState":"PROCESSING","newState":"COMPLETE"},"relationships":{"instance":{"data":{"type":"buildUploads","id":"xxx-xxx-xxx-xx-xxx"},"links":{"self":"https://api.appstoreconnect.apple.com/v1/buildUploads/xxx-xxx-xxx-xx-xxx"}}}}}'</span>
  <span class="c1"># 注意事項:</span>
  <span class="c1"># - `data:` はJSON文字列である必要があります。</span>
  <span class="c1"># - このレーンはローカルデバッグ用です（GETレスポンスを表示します）。</span>
  <span class="n">desc</span> <span class="s2">"[Automation] App Store ConnectのWebhookペイロードを処理し、ASC API経由で関連インスタンスを取得する"</span>
  <span class="n">lane</span> <span class="ss">:appStoreConnectWebhookHandler</span> <span class="k">do</span> <span class="p">\\</span><span class="o">|</span><span class="n">options</span><span class="p">\\</span><span class="o">|</span>
    <span class="k">begin</span>
      <span class="n">data</span> <span class="o">=</span> <span class="n">options</span><span class="p">[</span><span class="ss">:data</span><span class="p">]</span>
      <span class="no">UI</span><span class="p">.</span><span class="nf">user_error!</span><span class="p">(</span><span class="s2">"データがありません"</span><span class="p">)</span> <span class="k">if</span> <span class="n">data</span><span class="p">.</span><span class="nf">empty?</span>
      <span class="n">data</span> <span class="o">=</span> <span class="no">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
      <span class="n">url</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="nf">dig</span><span class="p">(</span><span class="s2">"data"</span><span class="p">,</span> <span class="s2">"relationships"</span><span class="p">,</span> <span class="s2">"instance"</span><span class="p">,</span> <span class="s2">"links"</span><span class="p">,</span> <span class="s2">"self"</span><span class="p">).</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">strip</span>
      <span class="no">UI</span><span class="p">.</span><span class="nf">user_error!</span><span class="p">(</span><span class="s2">"JSONにインスタンスのself URLがありません"</span><span class="p">)</span> <span class="k">if</span> <span class="n">url</span><span class="p">.</span><span class="nf">empty?</span>

      <span class="n">api_key</span> <span class="o">=</span> <span class="n">app_store_connect_api_key</span><span class="p">(</span>
        <span class="ss">key_id: </span><span class="s2">"xxxx"</span><span class="p">,</span>
        <span class="ss">issuer_id: </span><span class="s2">"xxxx-xxxx-xxxx-xxxx-165aa6465141"</span><span class="p">,</span>
        <span class="ss">key_filepath: </span><span class="s2">"./AuthKey_xxxx.p8"</span><span class="p">,</span>
        <span class="ss">duration: </span><span class="mi">1200</span><span class="p">,</span> <span class="c1"># 任意（最大1200）</span>
        <span class="ss">in_house: </span><span class="kp">false</span> <span class="c1"># 任意ですが、match/sigh使用時は必要な場合があります</span>
      <span class="p">)</span>

      <span class="n">loadAppStoreConnectAPIKey</span>
      <span class="c1">#</span>
      <span class="n">uri</span> <span class="o">=</span> <span class="no">URI</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
      <span class="n">http</span> <span class="o">=</span> <span class="no">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">uri</span><span class="p">.</span><span class="nf">host</span><span class="p">,</span> <span class="n">uri</span><span class="p">.</span><span class="nf">port</span><span class="p">)</span>
      <span class="n">http</span><span class="p">.</span><span class="nf">use_ssl</span> <span class="o">=</span> <span class="kp">true</span>
      <span class="n">http</span><span class="p">.</span><span class="nf">verify_mode</span> <span class="o">=</span> <span class="no">OpenSSL</span><span class="o">::</span><span class="no">SSL</span><span class="o">::</span><span class="no">VERIFY_PEER</span>
      <span class="n">store</span> <span class="o">=</span> <span class="no">OpenSSL</span><span class="o">::</span><span class="no">X509</span><span class="o">::</span><span class="no">Store</span><span class="p">.</span><span class="nf">new</span>
      <span class="n">store</span><span class="p">.</span><span class="nf">set_default_paths</span>
      <span class="n">http</span><span class="p">.</span><span class="nf">cert_store</span> <span class="o">=</span> <span class="n">store</span>

      <span class="n">request</span> <span class="o">=</span> <span class="no">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="o">::</span><span class="no">Get</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">uri</span><span class="p">.</span><span class="nf">request_uri</span><span class="p">)</span>
      <span class="n">token</span> <span class="o">=</span> <span class="no">Spaceship</span><span class="o">::</span><span class="no">ConnectAPI</span><span class="p">.</span><span class="nf">token</span>
      <span class="no">UI</span><span class="p">.</span><span class="nf">user_error!</span><span class="p">(</span><span class="s2">"App Store Connect APIトークンが利用できません。app_store_connect_api_keyの設定を確認してください。"</span><span class="p">)</span> <span class="k">if</span> <span class="n">token</span><span class="p">.</span><span class="nf">nil?</span>
      <span class="n">request</span><span class="p">[</span><span class="s1">'Authorization'</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"Bearer </span><span class="si">#{</span><span class="n">token</span><span class="p">.</span><span class="nf">text</span><span class="si">}</span><span class="s2">"</span>

      <span class="n">request</span><span class="p">[</span><span class="s1">'Content-Type'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'application/json'</span>
      <span class="n">request</span><span class="p">[</span><span class="s1">'Accept'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'application/json'</span>

      <span class="n">response</span> <span class="o">=</span> <span class="n">http</span><span class="p">.</span><span class="nf">request</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
      <span class="no">UI</span><span class="p">.</span><span class="nf">message</span><span class="p">(</span><span class="s2">"📡 GET </span><span class="si">#{</span><span class="n">url</span><span class="si">}</span><span class="s2"> レスポンス: [</span><span class="si">#{</span><span class="n">response</span><span class="p">.</span><span class="nf">code</span><span class="si">}</span><span class="s2">] </span><span class="si">#{</span><span class="n">response</span><span class="p">.</span><span class="nf">message</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
      <span class="no">UI</span><span class="p">.</span><span class="nf">message</span><span class="p">(</span><span class="n">response</span><span class="p">.</span><span class="nf">body</span><span class="p">)</span>
      <span class="c1">#</span>

      <span class="n">response</span>
      <span class="c1">## レスポンス処理...次のアクションを実行...</span>
      
    <span class="k">rescue</span> <span class="o">=&gt;</span> <span class="n">e</span>
        <span class="no">UI</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="s2">"❌ App Store Connect API Webhookの処理に失敗しました: </span><span class="si">#{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
    <span class="k">end</span>

  <span class="k">end</span>
</code></pre></div></div>

<h4 id="方法-2-webhook-エンドポイントで自分で処理する">方法 2— Webhook エンドポイントで自分で処理する</h4>

<p>二つ目の方法はWebhookエンドポイントのサービス上で全ての処理を完結させることですが、<strong>欠点はApp Store Connect APIキーをサービスに置く必要があり、自分でトークン検証を行わなければならないことです</strong>。</p>

<p><img src="/assets/7c0974856393/1*AUw59sLt97RquLhoRBp5Rw.webp" alt="" loading="lazy" decoding="async" width="1491" height="590" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDkxIiBoZWlnaHQ9IjU5MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/7c0974856393/1*AUw59sLt97RquLhoRBp5Rw.png" /></p>

<p><strong>Rubyの例：</strong></p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">require</span> <span class="s1">'jwt'</span>
<span class="k">require</span> <span class="s1">'net/http'</span>
<span class="k">require</span> <span class="s1">'time'</span>

<span class="n">keyFile</span> <span class="o">=</span> <span class="nc">File</span><span class="mf">.</span><span class="nf">read</span><span class="p">(</span><span class="s1">'./AuthKey_XXXX.p8'</span><span class="p">)</span> <span class="c1"># あなたの.p8秘密鍵ファイルに置き換えてください（App Store Connectからダウンロード）</span>
<span class="n">privateKey</span> <span class="o">=</span> <span class="nc">OpenSSL</span><span class="o">::</span><span class="nc">PKey</span><span class="o">::</span><span class="no">EC</span><span class="mf">.</span><span class="k">new</span><span class="p">(</span><span class="n">keyFile</span><span class="p">)</span>

<span class="n">payload</span> <span class="o">=</span> <span class="p">{</span>
            <span class="n">iss</span><span class="o">:</span> <span class="s1">'YOUR_ISSUE_ID'</span><span class="p">,</span> <span class="c1"># あなたのIssuer IDに置き換えてください（App Store Connectのユーザーアクセス-&gt;キー-&gt;App Store Connect APIページで取得）</span>
            <span class="n">iat</span><span class="o">:</span> <span class="nc">Time</span><span class="mf">.</span><span class="n">now</span><span class="mf">.</span><span class="n">to_i</span><span class="p">,</span>
            <span class="n">exp</span><span class="o">:</span> <span class="nc">Time</span><span class="mf">.</span><span class="n">now</span><span class="mf">.</span><span class="n">to_i</span> <span class="o">+</span> <span class="mi">60</span><span class="o">*</span><span class="mi">20</span><span class="p">,</span>
            <span class="n">aud</span><span class="o">:</span> <span class="s1">'appstoreconnect-v1'</span>
          <span class="p">}</span>

<span class="n">token</span> <span class="o">=</span> <span class="no">JWT</span><span class="mf">.</span><span class="n">encode</span> <span class="n">payload</span><span class="p">,</span> <span class="n">privateKey</span><span class="p">,</span> <span class="s1">'ES256'</span><span class="p">,</span> <span class="n">header_fields</span><span class="o">=</span><span class="p">{</span><span class="n">kid</span><span class="o">:</span><span class="s2">"YOUR_KEY_ID"</span><span class="p">,</span> <span class="n">typ</span><span class="o">:</span><span class="s2">"JWT"</span><span class="p">}</span> <span class="c1"># あなたのKey IDに置き換えてください（App Store Connectのユーザーアクセス-&gt;キー-&gt;App Store Connect APIページで取得）</span>
<span class="n">puts</span> <span class="n">token</span>

<span class="n">decoded_token</span> <span class="o">=</span> <span class="no">JWT</span><span class="mf">.</span><span class="n">decode</span> <span class="n">token</span><span class="p">,</span> <span class="n">privateKey</span><span class="p">,</span> <span class="kc">true</span><span class="p">,</span> <span class="p">{</span> <span class="n">algorithm</span><span class="o">:</span> <span class="s1">'ES256'</span> <span class="p">}</span>
<span class="n">puts</span> <span class="n">decoded_token</span>

<span class="c1"># Webhook Payload内のrelationshipsリンクに置き換えてください</span>
<span class="n">uri</span> <span class="o">=</span> <span class="nf">URI</span><span class="p">(</span><span class="s2">"https://api.appstoreconnect.apple.com/v1/apps/APPID/customerReviews"</span><span class="p">)</span> <span class="c1"># APPIDをApp Store ConnectのあなたのアプリIDに置き換えてください -&gt; あなたのアプリ -&gt; アプリ情報 -&gt; Apple ID</span>
<span class="n">https</span> <span class="o">=</span> <span class="nc">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="mf">.</span><span class="k">new</span><span class="p">(</span><span class="n">uri</span><span class="mf">.</span><span class="n">host</span><span class="p">,</span> <span class="n">uri</span><span class="mf">.</span><span class="n">port</span><span class="p">)</span>
<span class="n">https</span><span class="mf">.</span><span class="n">use_ssl</span> <span class="o">=</span> <span class="kc">true</span>

<span class="n">request</span> <span class="o">=</span> <span class="nc">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="o">::</span><span class="nc">Get</span><span class="mf">.</span><span class="k">new</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span>
<span class="n">request</span><span class="p">[</span><span class="s1">'Authorization'</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"Bearer #</span><span class="si">{</span><span class="nv">token</span><span class="si">}</span><span class="s2">"</span><span class="p">;</span>

<span class="n">response</span> <span class="o">=</span> <span class="n">https</span><span class="mf">.</span><span class="nf">request</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="n">puts</span> <span class="n">response</span><span class="mf">.</span><span class="n">read_body</span>
</code></pre></div></div>

<blockquote>
  <p><em>App Store Connect APIキーの生成方法、トークンの生成方法、APIの使用については「<a href="/posts/zrealm-dev/app-store-connect-api-customer-reviews-管理を強化-in-app-purchases-subscriptionsも対応-f1365e51902c/">App Store Connect API 現已支援 讀取和管理 Customer Reviews</a>」を参照してください。</em></p>
</blockquote>

<h3 id="app-store-connect-apiのレスポンス">App Store Connect APIのレスポンス</h3>

<p>ここでは、Webhookイベントを受け取った後にRelationships Linkを使って完全な情報を取得する際のレスポンス例をいくつか紹介します。</p>

<h4 id="ビルドバージョンアップロード--プロセス完了-1">ビルドバージョンアップロード — プロセス完了</h4>

<p><code class="language-plaintext highlighter-rouge">https://api.appstoreconnect.apple.com/v1/buildUploads/xxx-xx-xx-xx-xxx</code></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"buildUploads"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xx-xx-xx-xxx-xx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"cfBundleShortVersionString"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.101.0"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"cfBundleVersion"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"createdDate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-25T08:26:43-08:00"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"state"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"errors"</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span><span class="w">
        </span><span class="nl">"warnings"</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span><span class="w">
        </span><span class="nl">"infos"</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span><span class="w">
        </span><span class="nl">"state"</span><span class="p">:</span><span class="w"> </span><span class="s2">"COMPLETE"</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"platform"</span><span class="p">:</span><span class="w"> </span><span class="s2">"IOS"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"uploadedDate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-25T08:28:35-08:00"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"buildUploadFiles"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/buildUploads/xx-xx-xx-xxx-xx/relationships/buildUploadFiles"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/buildUploads/xx-xx-xx-xxx-xx/buildUploadFiles"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/buildUploads/xx-xx-xx-xxx-xx"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/buildUploads/xx-xx-xx-xxx-xx"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h4 id="ビルドバージョンアップロード--処理失敗-1">ビルドバージョンアップロード — 処理失敗</h4>

<p><code class="language-plaintext highlighter-rouge">https://api.appstoreconnect.apple.com/v1/buildUploads/xxx-xx-xx-xx-xxx</code></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"buildUploads"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xx-xx-xx-xx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"cfBundleShortVersionString"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.101.0"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"cfBundleVersion"</span><span class="p">:</span><span class="w"> </span><span class="s2">"3"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"createdDate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-12T09:03:32-08:00"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"state"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"errors"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"code"</span><span class="p">:</span><span class="w"> </span><span class="s2">"90683"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Info.plistに目的の文字列がありません。アプリのコードは、機密ユーザーデータにアクセスする1つ以上のAPIを参照しているか、またはそのようなアクセスを許可する1つ以上の権利を持っています。“My.app”バンドルのInfo.plistファイルには、アプリがデータを必要とする理由を明確かつ完全に説明するユーザー向けの目的文字列を含むNSMicrophoneUsageDescriptionキーが必要です。外部ライブラリやSDKを使用している場合、それらが目的文字列を必要とするAPIを参照している可能性があります。アプリがこれらのAPIを使用していなくても、目的文字列は必要です。詳細は以下をご覧ください：https://developer.apple.com/documentation/uikit/protecting_the_user_s_privacy/requesting_access_to_protected_resources."</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">],</span><span class="w">
        </span><span class="nl">"warnings"</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span><span class="w">
        </span><span class="nl">"infos"</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span><span class="w">
        </span><span class="nl">"state"</span><span class="p">:</span><span class="w"> </span><span class="s2">"FAILED"</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"platform"</span><span class="p">:</span><span class="w"> </span><span class="s2">"IOS"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"uploadedDate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-12T09:05:26-08:00"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"buildUploadFiles"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/buildUploads/xx-xx-xx-xx-xxx/relationships/buildUploadFiles"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/buildUploads/xx-xx-xx-xx-xxx/buildUploadFiles"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/buildUploads/xx-xx-xx-xx-xxx"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/buildUploads/xx-xx-xx-xx-xxx"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>ITMS-90683 を例にします。</p>

<h4 id="app-バージョンのステータス">App バージョンのステータス</h4>

<p><code class="language-plaintext highlighter-rouge">https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xx-xx-xx-xxx</code></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"appStoreVersions"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xxx-xxx-xxx"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"platform"</span><span class="p">:</span><span class="w"> </span><span class="s2">"IOS"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"versionString"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.101.0"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"appStoreState"</span><span class="p">:</span><span class="w"> </span><span class="s2">"READY_FOR_SALE"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"appVersionState"</span><span class="p">:</span><span class="w"> </span><span class="s2">"READY_FOR_DISTRIBUTION"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"copyright"</span><span class="p">:</span><span class="w"> </span><span class="s2">"© 2025 ZhgChgLi."</span><span class="p">,</span><span class="w">
      </span><span class="nl">"reviewType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"APP_STORE"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"releaseType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"MANUAL"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"earliestReleaseDate"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"usesIdfa"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
      </span><span class="nl">"downloadable"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"createdDate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-12-15T19:12:55-08:00"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"relationships"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"ageRatingDeclaration"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/ageRatingDeclaration"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/ageRatingDeclaration"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"appStoreVersionLocalizations"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/appStoreVersionLocalizations"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/appStoreVersionLocalizations"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"build"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/build"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/build"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"appStoreVersionPhasedRelease"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/appStoreVersionPhasedRelease"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/appStoreVersionPhasedRelease"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"gameCenterAppVersion"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/gameCenterAppVersion"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/gameCenterAppVersion"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"routingAppCoverage"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/routingAppCoverage"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/routingAppCoverage"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"appStoreReviewDetail"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/appStoreReviewDetail"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/appStoreReviewDetail"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"appStoreVersionSubmission"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/appStoreVersionSubmission"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/appStoreVersionSubmission"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"appClipDefaultExperience"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/appClipDefaultExperience"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/appClipDefaultExperience"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"appStoreVersionExperiments"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/appStoreVersionExperiments"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/appStoreVersionExperiments"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"appStoreVersionExperimentsV2"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/appStoreVersionExperimentsV2"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/appStoreVersionExperimentsV2"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"customerReviews"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/customerReviews"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/customerReviews"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="nl">"alternativeDistributionPackage"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
          </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/relationships/alternativeDistributionPackage"</span><span class="p">,</span><span class="w">
          </span><span class="nl">"related"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx/alternativeDistributionPackage"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.appstoreconnect.apple.com/v1/appStoreVersions/xxx-xxx-xxx-xxx"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<blockquote>
  <p><em>前述の通り、詳細なApp情報、バージョン番号、エラー原因はAPIを呼び出して取得する必要があります。</em></p>
</blockquote>

<h3 id="完了">完了</h3>

<p>これで App Store Connect API の Webhook を使って、App の CI/CD と自動化ワークフローをより良く整備し、チームの開発効率を向上させることができます。</p>

<h4 id="関連記事">関連記事</h4>

<ul>
  <li>
    <p><a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/"><strong>CI/CD 実践ガイド（1）：CI/CD とは？CI/CD を使って安定かつ効率的な開発チームを作るには？ツールの選び方は？</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/zreviewtender-無料オープンソースappレビュー監視ロボットで評価を即時把握-e36e48bb9265/">ZReviewTender — 無料オープンソースのAppレビュー監視ロボット</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/app-store-connect-api-customer-reviews-管理を強化-in-app-purchases-subscriptionsも対応-f1365e51902c/">App Store Connect API は現在、カスタマーレビューの読み取りと管理をサポートしています</a></p>
  </li>
</ul>

<p><em><a href="https://medium.com/zrealm-ios-dev/ci-cd-%E4%BD%BF%E7%94%A8-app-store-connect-api-webhook-%E4%B8%B2%E6%8E%A5%E8%87%AA%E5%8B%95%E5%8C%96%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B-7c0974856393" target="_blank">Post</a> Mediumから変換 by <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>.</em></p>]]></content>
  </entry><entry>
    <title type="html">iOS Timer｜DispatchSourceTimerの選び方と安全な使い方を徹底解説</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ios-timer-dispatchsourcetimer%E3%81%AE%E9%81%B8%E3%81%B3%E6%96%B9%E3%81%A8%E5%AE%89%E5%85%A8%E3%81%AA%E4%BD%BF%E3%81%84%E6%96%B9%E3%82%92%E5%BE%B9%E5%BA%95%E8%A7%A3%E8%AA%AC-62f68ebeecd3/" rel="alternate" type="text/html" title="iOS Timer｜DispatchSourceTimerの選び方と安全な使い方を徹底解説" />
    <published>2025-12-14T16:17:06+08:00</published>
    <updated>2025-12-15T00:24:36+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/62f68ebeecd3</id><summary type="html">有限状態機とデザインパターンでDispatchSourceTimerを安全に封装し、iOS Timerの使い分けと問題解決を実現。効率的で安全なタイマー管理を求める開発者必見。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="iosアプリ開発" /><category term="デザインパターン" /><category term="タイマー" /><category term="swift" /><category term="有限状態機械" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/62f68ebeecd3/1*2CWJW1fPOAZdU3nqeJ2JeQ.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ios-timer-dispatchsourcetimer%E3%81%AE%E9%81%B8%E3%81%B3%E6%96%B9%E3%81%A8%E5%AE%89%E5%85%A8%E3%81%AA%E4%BD%BF%E3%81%84%E6%96%B9%E3%82%92%E5%BE%B9%E5%BA%95%E8%A7%A3%E8%AA%AC-62f68ebeecd3/"><![CDATA[<h3 id="ios-timer-と-dispatchsourcetimer-の選び方と安全な使い方は">[iOS] Timer と DispatchSourceTimer の選び方と安全な使い方は？</h3>

<p>有限状態機とデザインパターンを使って DispatchSourceTimer をラップし、安全で使いやすくする。</p>

<p><img src="/assets/62f68ebeecd3/1*2CWJW1fPOAZdU3nqeJ2JeQ.webp" alt="Photo by Ralph Hutter" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/62f68ebeecd3/1*2CWJW1fPOAZdU3nqeJ2JeQ.jpeg" /></p>

<p>写真提供：<a href="https://unsplash.com/@pixelfreund?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" target="_blank">Ralph Hutter</a></p>

<h4 id="timer-について">Timer について</h4>

<p>iOS 開発では必ず遭遇するニーズの一つに「Timer タイマー」があります。UI 層でのカウントダウン表示やバナーのスライドショーから、データロジック層での定期的なイベント送信やデータの定期解放まで、目標達成のために Timer が必要です。</p>

<h3 id="foundation--timer-nstimer"><a href="https://developer.apple.com/documentation/foundation/timer" target="_blank">Foundation — Timer (NSTimer)</a></h3>

<p>Timer は誰もが直感的に最初に思い浮かべる API ですが、Timer を選択・使用する際には以下の点に注意する必要があります。</p>

<h4 id="長所と短所">長所と短所</h4>

<p><strong>Timer の利点：</strong></p>

<ul>
  <li>
    <p>デフォルトで UI 処理と統合されており、特にメインスレッドで実行する必要はありません。</p>
  </li>
  <li>
    <p>トリガータイミングの自動調整による電力使用の最適化</p>
  </li>
  <li>
    <p>複雑さは低く、最大で Retain Cycle が発生するか Timer の停止忘れが起こるが、直接的なクラッシュは発生しません</p>
  </li>
</ul>

<p><strong>Timer の欠点：</strong></p>

<ul>
  <li>
    <p>精度は RunLoop の状態に影響され、UI の高いインタラクションやモード切り替え時にトリガーが遅れる可能性があります</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">suspend</code>、<code class="language-plaintext highlighter-rouge">resume</code>、<code class="language-plaintext highlighter-rouge">activate</code>などの高度な操作はサポートしていません</p>
  </li>
</ul>

<h4 id="適したシーン">適したシーン</h4>

<p>UIレベルの要件、例えばバナーの自動スクロール（Auto Scroll ScrollView）やクーポン取得のカウントダウンなど、これらはユーザーが前景の現在の画面で内容に反応できれば十分な場合、私は直接 Timer を使います。簡単で迅速かつ安全に目的を達成できます。</p>

<h4 id="ライフサイクル">ライフサイクル</h4>

<p><img src="/assets/62f68ebeecd3/1*rQrIoCxCdwoFCgqZc1zE8A.webp" alt="" loading="lazy" decoding="async" width="1187" height="1237" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTg3IiBoZWlnaHQ9IjEyMzciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/62f68ebeecd3/1*rQrIoCxCdwoFCgqZc1zE8A.png" /></p>

<p>UI メインスレッド上で Timer を作成すると、Timer はメインスレッドの RunLoop によって強く保持され、RunLoop のポーリング機構を通じて定期的にトリガーされます。Timer は invalidate() が呼ばれるまで解放されません。そのため、ViewController で Timer を強く保持し、deinit 時に Timer の invalidate() を呼び出して、画面が終了した後に正しく Timer を終了・解放する必要があります。</p>

<ul>
  <li>
    <p>⭐️️️View Controller は Timer を強く保持し、<strong>Timer の実行ブロック（handler / closure）は必ず Weak Self にすること；さもなければ Retain Cycle になる。</strong></p>
  </li>
  <li>
    <p>⭐️️️View Controller のライフサイクル終了時に必ず Timer の invalidate() を呼び出してください。そうしないと RunLoop が Timer を保持し続けて動作し続けます。</p>
  </li>
</ul>

<blockquote>
  <p><em>RunLoop はスレッド内のイベント処理ループで、イベントの受信と処理を繰り返します；<strong>メインスレッドではシステムが自動的に RunLoop (RunLoop.main) を作成します</strong>が、それ以外のスレッドには必ずしも RunLoop が存在するとは限りません。</em></p>
</blockquote>

<h4 id="使用">使用</h4>

<p><code class="language-plaintext highlighter-rouge">Timer.scheduledTimer</code> を使って直接 Timer を宣言できます（RunLoop.main に自動的に追加され、<strong>Mode: .default</strong> になります）:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kd">class</span> <span class="kt">HomeViewController</span><span class="p">:</span> <span class="kt">UIViewController</span> <span class="p">{</span>
    
    <span class="kd">private</span> <span class="k">var</span> <span class="nv">timer</span><span class="p">:</span> <span class="kt">Timer</span><span class="p">?</span>
    
    <span class="kd">deinit</span> <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">invalidate</span><span class="p">()</span> <span class="c1">// タイマーを無効化</span>
        <span class="k">self</span><span class="o">.</span><span class="n">timer</span> <span class="o">=</span> <span class="kc">nil</span>
    <span class="p">}</span>

    <span class="k">override</span> <span class="kd">func</span> <span class="nf">viewDidLoad</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">super</span><span class="o">.</span><span class="nf">viewDidLoad</span><span class="p">()</span>
        <span class="nf">startCarousel</span><span class="p">()</span>
    <span class="p">}</span>
    
    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">startCarousel</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">timer</span> <span class="o">=</span> <span class="kt">Timer</span><span class="o">.</span><span class="nf">scheduledTimer</span><span class="p">(</span><span class="nv">withTimeInterval</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nv">repeats</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nv">block</span><span class="p">:</span> <span class="p">{</span> <span class="p">[</span><span class="k">weak</span> <span class="k">self</span><span class="p">]</span> <span class="n">_</span> <span class="k">in</span>
            <span class="k">self</span><span class="p">?</span><span class="o">.</span><span class="nf">doSomething</span><span class="p">()</span>
        <span class="p">})</span>
    <span class="p">}</span>

    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">doSomething</span><span class="p">()</span> <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"Hello World!"</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Timer オブジェクトを自分で宣言して RunLoop に追加することもできます:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">timer</span><span class="o">=</span> <span class="kt">Timer</span><span class="p">(</span><span class="nv">timeInterval</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nv">repeats</span><span class="p">:</span> <span class="kc">true</span><span class="p">)</span> <span class="p">{</span> <span class="p">[</span><span class="k">weak</span> <span class="k">self</span><span class="p">]</span> <span class="n">_</span> <span class="k">in</span>
  <span class="c1">// 何か処理を行う..</span>
<span class="p">}</span>
<span class="k">self</span><span class="o">.</span><span class="n">timer</span> <span class="o">=</span> <span class="n">timer</span>
<span class="c1">// RunLoopに追加して初めて実行が始まる</span>
<span class="kt">RunLoop</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="n">timer</span><span class="p">,</span> <span class="nv">forMode</span><span class="p">:</span> <span class="o">.</span><span class="k">default</span><span class="p">)</span>
</code></pre></div></div>

<h4 id="timer-の操作方法">Timer の操作方法</h4>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">invalidate()</code> は Timer を停止します</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">fire()</code> は即座に一度トリガーします</p>
  </li>
</ul>

<h4 id="runloop-mode-の影響">RunLoop <strong>Mode の影響</strong></h4>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">.default</code> ：デフォルトで追加されるモードで、主にUI表示を処理します。<br />
<strong><code class="language-plaintext highlighter-rouge">.tracking</code>モードに切り替わると一時的に停止します</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">.tracking</code> ：ScrollViewのスクロールやジェスチャーの処理。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">.common</code> ： <code class="language-plaintext highlighter-rouge">.default</code> と <code class="language-plaintext highlighter-rouge">.tracking</code> の両方を処理します。</p>
  </li>
</ul>

<blockquote>
  <p><em>⭐️️️⭐️️️⭐️️️そのため、デフォルトでは Timer は <code class="language-plaintext highlighter-rouge">.default</code> モードに追加されており、<strong>ユーザーが ScrollView をスクロールしたりジェスチャー操作を行うと自動的に一時停止</strong> し、操作が終了してから再開されます。そのため、Timer の発火が遅れたり、回数が予想より少なくなる可能性があります。</em></p>
</blockquote>

<p><strong>これに対して、Timer を .common モードに追加することで上記の問題を解決できます:</strong></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">RunLoop</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="n">timer</span><span class="p">,</span> <span class="nv">forMode</span><span class="p">:</span> <span class="o">.</span><span class="n">common</span><span class="p">)</span>
</code></pre></div></div>

<p>// メインのRunLoopにタイマーを.commonモードで追加する</p>

<h3 id="grand-central-dispatch--dispatchsourcetimer"><a href="https://developer.apple.com/documentation/dispatch/dispatchsourcetimer" target="_blank">Grand Central Dispatch — DispatchSourceTimer</a></h3>

<p>Timer のほかに、GCD はもう一つの DispatchSourceTimer という方法も提供しています。</p>

<h4 id="長所と短所-1">長所と短所</h4>

<p><strong>DispatchSourceTimer の利点：</strong></p>

<ul>
  <li>
    <p>操作の柔軟性（<code class="language-plaintext highlighter-rouge">suspend</code>、<code class="language-plaintext highlighter-rouge">resume</code> のサポート）が優れている</p>
  </li>
  <li>
    <p>高い精度と信頼性：GCDキューに依存</p>
  </li>
  <li>
    <p>leeway を設定して消費電力を制御可能</p>
  </li>
  <li>
    <p>安定して常駐するタスク（GCD キュー）</p>
  </li>
</ul>

<p><strong>DispatchSourceTimer の欠点：</strong></p>

<ul>
  <li>
    <p>UI操作は自分でメインスレッドに切り替える必要があります</p>
  </li>
  <li>
    <p>APIの使用は複雑で順序があり、<strong>誤用するとクラッシュします</strong></p>
  </li>
  <li>
    <p>安全に使用するにはラップが必要です</p>
  </li>
</ul>

<h4 id="適したシーン-1">適したシーン</h4>

<p>Timer が UI 層のシナリオに適しているのに対し、DispatchSourceTimer は UI やユーザーの現在の画面に関係ないタスクに適しています。最も一般的なのはトラッキングイベントの送信で、ユーザー操作によって生成されたイベントを定期的にサーバーに送信したり、不要な CoreData のデータを定期的にクリーンアップしたりする場合です。これらには DispatchSourceTimer が非常に適しています。</p>

<h4 id="ライフサイクル-1">ライフサイクル</h4>

<p><img src="/assets/62f68ebeecd3/1*2hIwImzm6ubpc5zK_roI3Q.webp" alt="" loading="lazy" decoding="async" width="1289" height="914" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjg5IiBoZWlnaHQ9IjkxNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/62f68ebeecd3/1*2hIwImzm6ubpc5zK_roI3Q.png" /></p>

<p>DispatchSourceTimer のライフサイクルは外部オブジェクトによって保持されているかどうかに依存します。GCD キュー自体はタイマーの所有者を強く保持せず、イベントのスケジューリングと実行のみを担当します。</p>

<h4 id="クラッシュ問題">クラッシュ問題</h4>

<p>DispatchSourceTimer は <code class="language-plaintext highlighter-rouge">activate</code>、<code class="language-plaintext highlighter-rouge">suspend</code>、<code class="language-plaintext highlighter-rouge">resume</code>、<code class="language-plaintext highlighter-rouge">cancel</code> といった多くの操作メソッドを提供していますが、非常に繊細で、呼び出し順序を間違えるとすぐにクラッシュ（EXC_BREAKPOINT/DispatchSourceTimer）してしまい、とても危険です。</p>

<p><img src="/assets/62f68ebeecd3/1*04cApJDt29a-98zgb9Wd2A.webp" alt="" loading="lazy" decoding="async" width="683" height="185" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2ODMiIGhlaWdodD0iMTg1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/62f68ebeecd3/1*04cApJDt29a-98zgb9Wd2A.png" /></p>

<p><strong>以下の場合はすべて直接クラッシュします：</strong></p>

<ul>
  <li>
    <p>❌ suspend() と resume() がペアで使われていない<br />
suspend() の後に再度 suspend() を呼んでいる<br />
resume() の後に再度 resume() を呼んでいる</p>
  </li>
  <li>
    <p>❌ suspend() の後に cancel() を呼ぶ場合<br />
先に resume() を呼んでから cancel() する必要があります。</p>
  </li>
  <li>
    <p>❌ suspend() 状態で Timer が解放される (nil になる)</p>
  </li>
  <li>
    <p>❌ cancel() の後に他の操作を呼ぶこと</p>
  </li>
</ul>

<h4 id="finite-state-machine有限状態機を使った操作のラップ">Finite-State Machine（有限状態機）を使った操作のラップ</h4>

<p>本記事のもう一つの重要なポイントに入ります。DispatchSourceTimerをどのように安全に使うか？</p>

<p><img src="/assets/62f68ebeecd3/1*S33K4OWFUPMocZvM4dLWvw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1151" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjExNTEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/62f68ebeecd3/1*S33K4OWFUPMocZvM4dLWvw.png" /></p>

<p>上図のように、有限状態機械を使って DispatchSourceTimer の操作をラップし、より安全で簡単に使用できるようにしました:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kd">class</span> <span class="kt">DispatchSourceTimerMachine</span> <span class="p">{</span>
    <span class="c1">// 有限状態機の状態一覧</span>
    <span class="kd">private</span> <span class="kd">enum</span> <span class="kt">TimerState</span> <span class="p">{</span>
        <span class="c1">// 初期状態</span>
        <span class="k">case</span> <span class="n">idle</span>
        <span class="c1">// 実行中</span>
        <span class="k">case</span> <span class="n">running</span>
        <span class="c1">// 一時停止中</span>
        <span class="k">case</span> <span class="n">suspended</span>
        <span class="c1">// 終了中</span>
        <span class="k">case</span> <span class="n">cancelled</span>
    <span class="p">}</span>

    <span class="kd">private</span> <span class="k">var</span> <span class="nv">timer</span><span class="p">:</span> <span class="kt">DispatchSourceTimer</span><span class="p">?</span>
    <span class="kd">private</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">timerQueue</span><span class="p">:</span> <span class="kt">DispatchQueue</span> <span class="o">=</span> <span class="p">{</span>
        <span class="kt">DispatchQueue</span><span class="p">(</span><span class="nv">label</span><span class="p">:</span> <span class="s">"li.zhgchg.DispatchSourceTimerMachine"</span><span class="p">,</span> <span class="nv">qos</span><span class="p">:</span> <span class="o">.</span><span class="n">background</span><span class="p">)</span>
    <span class="p">}()</span>

    <span class="kd">private</span> <span class="k">var</span> <span class="nv">_state</span><span class="p">:</span> <span class="kt">TimerState</span> <span class="o">=</span> <span class="o">.</span><span class="n">idle</span>
    
    <span class="kd">deinit</span> <span class="p">{</span>
        <span class="c1">// オーナーオブジェクトが消える時にタイマーを同期的にキャンセル</span>
        <span class="c1">// しなくても問題ない（handlerはweak）が、処理の流れを保証するため</span>
        <span class="k">if</span> <span class="n">_state</span> <span class="o">==</span> <span class="o">.</span><span class="n">suspended</span> <span class="p">{</span>
            <span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
            <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">running</span>
        <span class="p">}</span>
        <span class="k">if</span> <span class="n">_state</span> <span class="o">==</span> <span class="o">.</span><span class="n">running</span> <span class="p">{</span>
            <span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">cancel</span><span class="p">()</span>
            <span class="n">timer</span> <span class="o">=</span> <span class="kc">nil</span>
            <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">cancelled</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// タイマーを起動</span>
    <span class="kd">func</span> <span class="nf">activate</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="kt">DispatchTimeInterval</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="kt">DispatchSource</span><span class="o">.</span><span class="kt">DispatchSourceHandler</span><span class="p">?)</span> <span class="p">{</span>
        <span class="c1">// idle, cancelled 状態のみタイマーを起動可能</span>
        <span class="k">guard</span> <span class="p">[</span><span class="o">.</span><span class="n">idle</span><span class="p">,</span> <span class="o">.</span><span class="n">cancelled</span><span class="p">]</span><span class="o">.</span><span class="nf">contains</span><span class="p">(</span><span class="n">_state</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
        
        <span class="c1">// タイマーを作成し activate() を呼ぶ</span>
        <span class="k">let</span> <span class="nv">timer</span> <span class="o">=</span> <span class="nf">makeTimer</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="n">repeatTimeInterval</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="n">handler</span><span class="p">)</span>
        <span class="k">self</span><span class="o">.</span><span class="n">timer</span> <span class="o">=</span> <span class="n">timer</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">activate</span><span class="p">()</span>
        
        <span class="c1">// running 状態に切り替え</span>
        <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">running</span>
    <span class="p">}</span>

    <span class="c1">// タイマーを一時停止</span>
    <span class="kd">func</span> <span class="nf">suspend</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// running 状態のみ一時停止可能</span>
        <span class="k">guard</span> <span class="p">[</span><span class="o">.</span><span class="n">running</span><span class="p">]</span><span class="o">.</span><span class="nf">contains</span><span class="p">(</span><span class="n">_state</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
        
        <span class="c1">// タイマーを一時停止</span>
        <span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">suspend</span><span class="p">()</span>
        
        <span class="c1">// suspended 状態に切り替え</span>
        <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">suspended</span>
    <span class="p">}</span>

    <span class="c1">// タイマーを再開</span>
    <span class="kd">func</span> <span class="nf">resume</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// suspended 状態のみ再開可能</span>
        <span class="k">guard</span> <span class="p">[</span><span class="o">.</span><span class="n">suspended</span><span class="p">]</span><span class="o">.</span><span class="nf">contains</span><span class="p">(</span><span class="n">_state</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
        
        <span class="c1">// タイマーを再開</span>
        <span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
        
        <span class="c1">// running 状態に切り替え</span>
        <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">running</span>
    <span class="p">}</span>

    <span class="c1">// タイマーを終了</span>
    <span class="kd">func</span> <span class="nf">cancel</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// suspended, running 状態のみ終了可能</span>
        <span class="k">guard</span> <span class="p">[</span><span class="o">.</span><span class="n">suspended</span><span class="p">,</span> <span class="o">.</span><span class="n">running</span><span class="p">]</span><span class="o">.</span><span class="nf">contains</span><span class="p">(</span><span class="n">_state</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
        
        <span class="c1">// 現在 suspended 状態なら resume() してから終了</span>
        <span class="c1">// これは DispatchSourceTimer の制約で、running 状態でないと cancel() できないため</span>
        <span class="k">if</span> <span class="n">_state</span> <span class="o">==</span> <span class="o">.</span><span class="n">suspended</span> <span class="p">{</span>
            <span class="k">self</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
        <span class="p">}</span>

        <span class="c1">// タイマーを終了</span>
        <span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">cancel</span><span class="p">()</span>
        <span class="n">timer</span> <span class="o">=</span> <span class="kc">nil</span>
        
        <span class="c1">// cancelled 状態に切り替え</span>
        <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">cancelled</span>
    <span class="p">}</span>
    
    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">makeTimer</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="kt">DispatchTimeInterval</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="kt">DispatchSourceProtocol</span><span class="o">.</span><span class="kt">DispatchSourceHandler</span><span class="p">?)</span> <span class="o">-&gt;</span> <span class="kt">DispatchSourceTimer</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">timer</span> <span class="o">=</span> <span class="kt">DispatchSource</span><span class="o">.</span><span class="nf">makeTimerSource</span><span class="p">(</span><span class="nv">queue</span><span class="p">:</span> <span class="n">timerQueue</span><span class="p">)</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">schedule</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">(),</span> <span class="nv">repeating</span><span class="p">:</span> <span class="n">repeatTimeInterval</span><span class="p">)</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">setEventHandler</span><span class="p">(</span><span class="nv">qos</span><span class="p">:</span> <span class="o">.</span><span class="n">background</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="n">handler</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">timer</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>私たちは簡単に有限状態機械を使って、「状態がどの状態に遷移できるか」と「状態で何をするか」のロジックをカプセル化しました。誤った状態で呼び出しても無視され（クラッシュしません）、さらにいくつかの最適化も行いました。例えば、suspended 状態でも cancel が可能で、cancelled 状態から再度 activate できるようにしています。</p>

<blockquote>
  <p><strong><em>関連記事：</em></strong></p>
</blockquote>

<blockquote>
  <p><em>以前に書いた別の記事「 <a href="https://zhgchg.li/posts/pinkoi-engineering/design-patterns-%E5%AF%A6%E6%88%B0%E6%87%89%E7%94%A8-%E5%B0%81%E8%A3%9D-socket-io-%E5%8D%B3%E6%99%82%E9%80%9A%E8%A8%8A%E6%9E%B6%E6%A7%8B%E8%88%87%E4%B8%83%E5%A4%A7%E8%A8%AD%E8%A8%88%E6%A8%A1%E5%BC%8F%E8%A7%A3%E6%9E%90-78507a8de6a5/#%E9%9C%80%E6%B1%82%E5%A0%B4%E6%99%AF-3" target="_blank">Design Patterns 實戰應用｜封裝 Socket.IO 即時通訊架構</a> 」でも有限状態機械を使用し、さらに State Pattern も多用しています。</em></p>
</blockquote>

<blockquote>
  <p><em>Finite-State Machine 有限状態機：状態間の遷移制御とやるべきことに注目する。</em></p>
</blockquote>

<blockquote>
  <p><em>State Pattern: 各状態内の振る舞いロジックに注目する。</em></p>
</blockquote>

<h4 id="serial-queue-を使った有限状態機の状態遷移操作">Serial Queue を使った有限状態機の状態遷移操作</h4>

<p>状態機で DispatchSourceTimer の安全な使用を確保した後も終わりではありません。DispatchSourceTimerMachine を呼び出す外部が同じスレッドであるとは限らず、異なるスレッドでこのオブジェクトを操作するとレースコンディションが発生し、クラッシュの原因となります。</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kd">class</span> <span class="kt">DispatchSourceTimerMachine</span> <span class="p">{</span>
    <span class="c1">// 有限状態機の状態一覧</span>
    <span class="kd">private</span> <span class="kd">enum</span> <span class="kt">TimerState</span> <span class="p">{</span>
        <span class="c1">// 初期状態</span>
        <span class="k">case</span> <span class="n">idle</span>
        <span class="c1">// 実行中</span>
        <span class="k">case</span> <span class="n">running</span>
        <span class="c1">// 一時停止中</span>
        <span class="k">case</span> <span class="n">suspended</span>
        <span class="c1">// 取消し中</span>
        <span class="k">case</span> <span class="n">cancelled</span>
    <span class="p">}</span>

    <span class="kd">private</span> <span class="k">var</span> <span class="nv">timer</span><span class="p">:</span> <span class="kt">DispatchSourceTimer</span><span class="p">?</span>
    <span class="kd">private</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">timerQueue</span><span class="p">:</span> <span class="kt">DispatchQueue</span> <span class="o">=</span> <span class="p">{</span>
        <span class="kt">DispatchQueue</span><span class="p">(</span><span class="nv">label</span><span class="p">:</span> <span class="s">"li.zhgchg.DispatchSourceTimerMachine"</span><span class="p">,</span> <span class="nv">qos</span><span class="p">:</span> <span class="o">.</span><span class="n">background</span><span class="p">)</span>
    <span class="p">}()</span>

    <span class="kd">private</span> <span class="k">var</span> <span class="nv">_state</span><span class="p">:</span> <span class="kt">TimerState</span> <span class="o">=</span> <span class="o">.</span><span class="n">idle</span>

    <span class="kd">private</span> <span class="kd">static</span> <span class="k">let</span> <span class="nv">operationQueueSpecificKey</span> <span class="o">=</span> <span class="kt">DispatchSpecificKey</span><span class="o">&lt;</span><span class="kt">ObjectIdentifier</span><span class="o">&gt;</span><span class="p">()</span>
    <span class="kd">private</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">operationQueueSpecificValue</span><span class="p">:</span> <span class="kt">ObjectIdentifier</span> <span class="o">=</span> <span class="kt">ObjectIdentifier</span><span class="p">(</span><span class="k">self</span><span class="p">)</span>
    <span class="kd">private</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">operationQueue</span><span class="p">:</span> <span class="kt">DispatchQueue</span> <span class="o">=</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">queue</span> <span class="o">=</span> <span class="kt">DispatchQueue</span><span class="p">(</span><span class="nv">label</span><span class="p">:</span> <span class="s">"li.zhgchg.DispatchSourceTimerMachine.operationQueue"</span><span class="p">)</span>
        <span class="n">queue</span><span class="o">.</span><span class="nf">setSpecific</span><span class="p">(</span><span class="nv">key</span><span class="p">:</span> <span class="k">Self</span><span class="o">.</span><span class="n">operationQueueSpecificKey</span><span class="p">,</span> <span class="nv">value</span><span class="p">:</span> <span class="n">operationQueueSpecificValue</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">queue</span>
    <span class="p">}()</span>
    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">operation</span><span class="p">(</span><span class="nv">async</span><span class="p">:</span> <span class="kt">Bool</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span> <span class="n">_</span> <span class="nv">work</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="kt">DispatchQueue</span><span class="o">.</span><span class="nf">getSpecific</span><span class="p">(</span><span class="nv">key</span><span class="p">:</span> <span class="k">Self</span><span class="o">.</span><span class="n">operationQueueSpecificKey</span><span class="p">)</span> <span class="o">==</span> <span class="n">operationQueueSpecificValue</span> <span class="p">{</span>
            <span class="nf">work</span><span class="p">()</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">if</span> <span class="k">async</span> <span class="p">{</span>
                <span class="n">operationQueue</span><span class="o">.</span><span class="nf">async</span><span class="p">(</span><span class="nv">execute</span><span class="p">:</span> <span class="n">work</span><span class="p">)</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="n">operationQueue</span><span class="o">.</span><span class="nf">sync</span><span class="p">(</span><span class="nv">execute</span><span class="p">:</span> <span class="n">work</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
    
    <span class="kd">deinit</span> <span class="p">{</span>
        <span class="c1">// オーナーオブジェクトが消えるとき、同期的にタイマーをキャンセル</span>
        <span class="c1">// しなくても影響はない（handlerはweak）が、処理の整合性を保つため</span>
        <span class="c1">// sync実行完了を保証</span>
        <span class="nf">operation</span><span class="p">(</span><span class="nv">async</span><span class="p">:</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span> <span class="p">[</span><span class="k">self</span><span class="p">]</span> <span class="k">in</span>
            <span class="k">if</span> <span class="n">_state</span> <span class="o">==</span> <span class="o">.</span><span class="n">suspended</span> <span class="p">{</span>
                <span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
                <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">running</span>
            <span class="p">}</span>
            <span class="k">if</span> <span class="n">_state</span> <span class="o">==</span> <span class="o">.</span><span class="n">running</span> <span class="p">{</span>
                <span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">cancel</span><span class="p">()</span>
                <span class="n">timer</span> <span class="o">=</span> <span class="kc">nil</span>
                <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">cancelled</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// タイマーを起動</span>
    <span class="kd">func</span> <span class="nf">activate</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="kt">DispatchTimeInterval</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="kt">DispatchSource</span><span class="o">.</span><span class="kt">DispatchSourceHandler</span><span class="p">?)</span> <span class="p">{</span>
        <span class="n">operation</span> <span class="p">{</span> <span class="p">[</span><span class="k">weak</span> <span class="k">self</span><span class="p">]</span> <span class="k">in</span>
            <span class="k">guard</span> <span class="k">let</span> <span class="nv">self</span> <span class="o">=</span> <span class="k">self</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
            <span class="c1">// idle、cancelled状態のみタイマーを起動可能</span>
            <span class="k">guard</span> <span class="p">[</span><span class="o">.</span><span class="n">idle</span><span class="p">,</span> <span class="o">.</span><span class="n">cancelled</span><span class="p">]</span><span class="o">.</span><span class="nf">contains</span><span class="p">(</span><span class="n">_state</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
            
            <span class="c1">// タイマーを作成しactivate()</span>
            <span class="k">let</span> <span class="nv">timer</span> <span class="o">=</span> <span class="nf">makeTimer</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="n">repeatTimeInterval</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="n">handler</span><span class="p">)</span>
            <span class="k">self</span><span class="o">.</span><span class="n">timer</span> <span class="o">=</span> <span class="n">timer</span>
            <span class="n">timer</span><span class="o">.</span><span class="nf">activate</span><span class="p">()</span>
            
            <span class="c1">// running状態に切り替え</span>
            <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">running</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// タイマーを一時停止</span>
    <span class="kd">func</span> <span class="nf">suspend</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">operation</span> <span class="p">{</span> <span class="p">[</span><span class="k">weak</span> <span class="k">self</span><span class="p">]</span> <span class="k">in</span>
            <span class="k">guard</span> <span class="k">let</span> <span class="nv">self</span> <span class="o">=</span> <span class="k">self</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
            <span class="c1">// running状態のみ一時停止可能</span>
            <span class="k">guard</span> <span class="p">[</span><span class="o">.</span><span class="n">running</span><span class="p">]</span><span class="o">.</span><span class="nf">contains</span><span class="p">(</span><span class="n">_state</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
            
            <span class="c1">// タイマーを一時停止</span>
            <span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">suspend</span><span class="p">()</span>
            
            <span class="c1">// suspended状態に切り替え</span>
            <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">suspended</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// タイマーを再開</span>
    <span class="kd">func</span> <span class="nf">resume</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">operation</span> <span class="p">{</span> <span class="p">[</span><span class="k">weak</span> <span class="k">self</span><span class="p">]</span> <span class="k">in</span>
            <span class="k">guard</span> <span class="k">let</span> <span class="nv">self</span> <span class="o">=</span> <span class="k">self</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
            <span class="c1">// suspended状態のみ再開可能</span>
            <span class="k">guard</span> <span class="p">[</span><span class="o">.</span><span class="n">suspended</span><span class="p">]</span><span class="o">.</span><span class="nf">contains</span><span class="p">(</span><span class="n">_state</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
            
            <span class="c1">// タイマーを再開</span>
            <span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
            
            <span class="c1">// running状態に切り替え</span>
            <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">running</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// タイマーを終了</span>
    <span class="kd">func</span> <span class="nf">cancel</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">operation</span> <span class="p">{</span> <span class="p">[</span><span class="k">weak</span> <span class="k">self</span><span class="p">]</span> <span class="k">in</span>
            <span class="k">guard</span> <span class="k">let</span> <span class="nv">self</span> <span class="o">=</span> <span class="k">self</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
            <span class="c1">// suspended、running状態のみ終了可能</span>
            <span class="k">guard</span> <span class="p">[</span><span class="o">.</span><span class="n">suspended</span><span class="p">,</span> <span class="o">.</span><span class="n">running</span><span class="p">]</span><span class="o">.</span><span class="nf">contains</span><span class="p">(</span><span class="n">_state</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
            
            <span class="c1">// suspended状態の場合は先にresume()してから終了</span>
            <span class="c1">// これはDispatchSourceTimerの制限で、running状態でないとcancelできないため</span>
            <span class="k">if</span> <span class="n">_state</span> <span class="o">==</span> <span class="o">.</span><span class="n">suspended</span> <span class="p">{</span>
                <span class="k">self</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
            <span class="p">}</span>
            
            <span class="c1">// タイマーをキャンセル</span>
            <span class="n">timer</span><span class="p">?</span><span class="o">.</span><span class="nf">cancel</span><span class="p">()</span>
            <span class="n">timer</span> <span class="o">=</span> <span class="kc">nil</span>
            
            <span class="c1">// cancelled状態に切り替え</span>
            <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">cancelled</span>
        <span class="p">}</span>
    <span class="p">}</span>
    
    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">makeTimer</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="kt">DispatchTimeInterval</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="kt">DispatchSourceProtocol</span><span class="o">.</span><span class="kt">DispatchSourceHandler</span><span class="p">?)</span> <span class="o">-&gt;</span> <span class="kt">DispatchSourceTimer</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">timer</span> <span class="o">=</span> <span class="kt">DispatchSource</span><span class="o">.</span><span class="nf">makeTimerSource</span><span class="p">(</span><span class="nv">queue</span><span class="p">:</span> <span class="n">timerQueue</span><span class="p">)</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">schedule</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">(),</span> <span class="nv">repeating</span><span class="p">:</span> <span class="n">repeatTimeInterval</span><span class="p">)</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">setEventHandler</span><span class="p">(</span><span class="nv">qos</span><span class="p">:</span> <span class="o">.</span><span class="n">background</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="n">handler</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">timer</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>現在、私たちは安全に <code class="language-plaintext highlighter-rouge">DispatchSourceTimerMachine</code> オブジェクトを Timer として安心して使用できます:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">final</span> <span class="kd">class</span> <span class="nc">TrackingEventSender</span> <span class="p">{</span>

    <span class="k">private</span> <span class="kd">let</span> <span class="nx">timerMachine</span> <span class="o">=</span> <span class="nc">DispatchSourceTimerMachine</span><span class="p">()</span>
    <span class="k">public</span> <span class="kd">var</span> <span class="nx">events</span><span class="p">:</span> <span class="p">[</span><span class="nb">String</span><span class="p">:</span> <span class="nb">String</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="c1">// 定期トラッキングを開始する</span>
    <span class="nx">func</span> <span class="nf">startTracking</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">timerMachine</span><span class="p">.</span><span class="nf">activate</span><span class="p">(</span><span class="nx">repeatTimeInterval</span><span class="p">:</span> <span class="p">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">30</span><span class="p">))</span> <span class="p">{</span> <span class="p">[</span><span class="nx">weak</span> <span class="nb">self</span><span class="p">]</span> <span class="k">in</span>
            <span class="nb">self</span><span class="p">?.</span><span class="nf">sendTrackingEvent</span><span class="p">()</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// トラッキングを一時停止する（例：アプリがバックグラウンドに入るとき）</span>
    <span class="nx">func</span> <span class="nf">pauseTracking</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">timerMachine</span><span class="p">.</span><span class="nf">suspend</span><span class="p">()</span>
    <span class="p">}</span>

    <span class="c1">// トラッキングを再開する（例：アプリがフォアグラウンドに戻るとき）</span>
    <span class="nx">func</span> <span class="nf">resumeTracking</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">timerMachine</span><span class="p">.</span><span class="nf">resume</span><span class="p">()</span>
    <span class="p">}</span>

    <span class="c1">// トラッキングを停止する（例：画面を離れるとき）</span>
    <span class="nx">func</span> <span class="nf">stopTracking</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">timerMachine</span><span class="p">.</span><span class="nf">cancel</span><span class="p">()</span>
    <span class="p">}</span>

    <span class="k">private</span> <span class="nx">func</span> <span class="nf">sendTrackingEvent</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// サーバーにイベントを送信する...</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>ここまでで DispatchSourceTimer を安全に使用する方法について説明しました。次に、いくつかのデザインパターンの活用について紹介し、オブジェクトの抽象化によるテストの容易化や DispatchSourceHandler の実行ロジックの抽象化を行います。</p>

<h4 id="拡張--adapterパターン--factoryパターンを使って-dispatchsourcetimer-を生成抽象化テストに便利">拡張 — Adapterパターン + Factoryパターンを使って DispatchSourceTimer を生成（抽象化テストに便利）</h4>

<p>DispatchSourceTimer は GCD の Objective-C オブジェクトであり、テスト時に Mock するのが難しい（Protocol がない）ため、自分で Protocol と Factory Pattern を定義して生成し、TimerStateMachine をテスト可能にする必要があります。</p>

<p><strong>Adapterパターン— DispatchSourceTimer操作のラップ:</strong></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">protocol</span> <span class="kt">TimerAdapter</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">schedule</span><span class="p">(</span><span class="nv">repeating</span><span class="p">:</span> <span class="kt">DispatchTimeInterval</span><span class="p">)</span>
    <span class="kd">func</span> <span class="nf">setEventHandler</span><span class="p">(</span><span class="nv">handler</span><span class="p">:</span> <span class="kt">DispatchSourceProtocol</span><span class="o">.</span><span class="kt">DispatchSourceHandler</span><span class="p">?)</span>
    <span class="kd">func</span> <span class="nf">activate</span><span class="p">()</span>
    <span class="kd">func</span> <span class="nf">suspend</span><span class="p">()</span>
    <span class="kd">func</span> <span class="nf">resume</span><span class="p">()</span>
    <span class="kd">func</span> <span class="nf">cancel</span><span class="p">()</span>
<span class="p">}</span>

<span class="c1">// DispatchSourceTimer の Adapter 実装</span>
<span class="kd">final</span> <span class="kd">class</span> <span class="kt">DispatchSourceTimerAdapter</span><span class="p">:</span> <span class="kt">TimerAdapter</span> <span class="p">{</span>
    <span class="c1">// 元の DispatchSourceTimer</span>
    <span class="kd">private</span> <span class="k">let</span> <span class="nv">timer</span><span class="p">:</span> <span class="kt">DispatchSourceTimer</span>

    <span class="nf">init</span><span class="p">(</span><span class="nv">label</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"li.zhgchg.DispatchSourceTimerAdapter"</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">queue</span> <span class="o">=</span> <span class="kt">DispatchQueue</span><span class="p">(</span><span class="nv">label</span><span class="p">:</span> <span class="n">label</span><span class="p">,</span> <span class="nv">qos</span><span class="p">:</span> <span class="o">.</span><span class="n">background</span><span class="p">)</span>
        <span class="k">let</span> <span class="nv">timer</span> <span class="o">=</span> <span class="kt">DispatchSource</span><span class="o">.</span><span class="nf">makeTimerSource</span><span class="p">(</span><span class="nv">queue</span><span class="p">:</span> <span class="n">queue</span><span class="p">)</span>
        <span class="k">self</span><span class="o">.</span><span class="n">timer</span> <span class="o">=</span> <span class="n">timer</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">schedule</span><span class="p">(</span><span class="nv">repeating</span><span class="p">:</span> <span class="kt">DispatchTimeInterval</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">schedule</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">(),</span> <span class="nv">repeating</span><span class="p">:</span> <span class="n">repeating</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">setEventHandler</span><span class="p">(</span><span class="nv">handler</span><span class="p">:</span> <span class="kt">DispatchSourceProtocol</span><span class="o">.</span><span class="kt">DispatchSourceHandler</span><span class="p">?)</span> <span class="p">{</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">setEventHandler</span><span class="p">(</span><span class="nv">qos</span><span class="p">:</span> <span class="o">.</span><span class="n">background</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="n">handler</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">activate</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">activate</span><span class="p">()</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">suspend</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">suspend</span><span class="p">()</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">resume</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">cancel</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">cancel</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><strong>Factory Pattern — TimerAdapter を生成する抽象的な方法:</strong></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">DispatchSourceTimerAdapterFactorySpec</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">makeTimer</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="kt">DispatchTimeInterval</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="kt">DispatchSourceProtocol</span><span class="o">.</span><span class="kt">DispatchSourceHandler</span><span class="p">?)</span> <span class="o">-&gt;</span> <span class="kt">TimerAdapter</span>
<span class="p">}</span>

<span class="c1">// DispatchSourceTimerAdapter の生成手順をカプセル化</span>
<span class="kd">final</span> <span class="kd">class</span> <span class="kt">DispatchSourceTimerAdapterFactory</span><span class="p">:</span> <span class="kt">DispatchSourceTimerAdapterFactorySpec</span> <span class="p">{</span>
    <span class="kd">public</span> <span class="kd">func</span> <span class="nf">makeTimer</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="kt">DispatchTimeInterval</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="kt">DispatchSourceProtocol</span><span class="o">.</span><span class="kt">DispatchSourceHandler</span><span class="p">?)</span> <span class="o">-&gt;</span> <span class="kt">TimerAdapter</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">timer</span> <span class="o">=</span> <span class="kt">DispatchSourceTimerAdapter</span><span class="p">()</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">schedule</span><span class="p">(</span><span class="nv">repeating</span><span class="p">:</span> <span class="n">repeatTimeInterval</span><span class="p">)</span>
        <span class="n">timer</span><span class="o">.</span><span class="nf">setEventHandler</span><span class="p">(</span><span class="nv">handler</span><span class="p">:</span> <span class="n">handler</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">timer</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><strong>組み合わせて使用:</strong></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">stateMachine</span> <span class="o">=</span> <span class="kt">DispatchSourceTimerMachine</span><span class="p">(</span><span class="nv">timerFactory</span><span class="p">:</span> <span class="kt">DispatchSourceTimerAdapterFactory</span><span class="p">())</span>

<span class="c1">//</span>
<span class="kd">final</span> <span class="kd">class</span> <span class="kt">DispatchSourceTimerMachine</span> <span class="p">{</span>
    <span class="c1">// 略..</span>
    <span class="kd">private</span> <span class="k">var</span> <span class="nv">timer</span><span class="p">:</span> <span class="kt">TimerAdapter</span><span class="p">?</span>
    <span class="kd">private</span> <span class="k">let</span> <span class="nv">timerFactory</span><span class="p">:</span> <span class="kt">DispatchSourceTimerAdapterFactorySpec</span>
    <span class="kd">public</span> <span class="nf">init</span><span class="p">(</span><span class="nv">timerFactory</span><span class="p">:</span> <span class="kt">DispatchSourceTimerAdapterFactorySpec</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">timerFactory</span> <span class="o">=</span> <span class="n">timerFactory</span>
    <span class="p">}</span>
    <span class="c1">// 略..</span>

    <span class="kd">func</span> <span class="nf">activate</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="kt">DispatchTimeInterval</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="kt">DispatchSource</span><span class="o">.</span><span class="kt">DispatchSourceHandler</span><span class="p">?)</span> <span class="p">{</span>
        <span class="n">onQueue</span> <span class="p">{</span> <span class="p">[</span><span class="k">weak</span> <span class="k">self</span><span class="p">]</span> <span class="k">in</span>
            <span class="k">guard</span> <span class="k">let</span> <span class="nv">self</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
            <span class="k">guard</span> <span class="p">[</span><span class="o">.</span><span class="n">idle</span><span class="p">,</span> <span class="o">.</span><span class="n">cancelled</span><span class="p">]</span><span class="o">.</span><span class="nf">contains</span><span class="p">(</span><span class="n">_state</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
            <span class="c1">// Factoryを使ってタイマーを作成</span>
            <span class="k">let</span> <span class="nv">timer</span> <span class="o">=</span> <span class="n">timerFactory</span><span class="o">.</span><span class="nf">makeTimer</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="n">repeatTimeInterval</span><span class="p">,</span> <span class="nv">handler</span><span class="p">:</span> <span class="n">handler</span><span class="p">)</span>
            <span class="k">self</span><span class="o">.</span><span class="n">timer</span> <span class="o">=</span> <span class="n">timer</span>

            <span class="n">timer</span><span class="o">.</span><span class="nf">activate</span><span class="p">()</span>
            <span class="n">_state</span> <span class="o">=</span> <span class="o">.</span><span class="n">running</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// 略..</span>
<span class="p">}</span>
</code></pre></div></div>

<p>これで <code class="language-plaintext highlighter-rouge">TimerAdapter</code> / <code class="language-plaintext highlighter-rouge">DispatchSourceTimerAdapterFactorySpec</code> のテスト段階で Mock Object を作成して単体テストを実行できます。</p>

<h4 id="拡張--strategy-パターンを使った-dispatchsourcehandler-のラップ">拡張 — <strong><em>Strategy</em></strong> パターンを使った DispatchSourceHandler のラップ</h4>

<p>DispatchSourceHandler が実行する処理を動的に変更したい場合、Strategy パターンを使って作業内容をカプセル化できます。</p>

<p><strong>TrackingHandlerStrategy:</strong></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">TrackingHandlerStrategy</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">target</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
    <span class="kd">func</span> <span class="nf">execute</span><span class="p">()</span>
<span class="p">}</span>

<span class="c1">// ホームイベント</span>
<span class="kd">final</span> <span class="kd">class</span> <span class="kt">HomeTrackingHandlerStrategy</span><span class="p">:</span> <span class="kt">TrackingHandlerStrategy</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">target</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"home"</span>
    <span class="kd">func</span> <span class="nf">execute</span><span class="p">()</span> <span class="p">{</span>
       <span class="c1">// ホームイベントログを取得して送信</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// プロダクトイベント</span>
<span class="kd">final</span> <span class="kd">class</span> <span class="kt">ProductTrackingHandlerStrategy</span><span class="p">:</span> <span class="kt">TrackingHandlerStrategy</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">target</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"product"</span>
    <span class="kd">func</span> <span class="nf">execute</span><span class="p">()</span> <span class="p">{</span>
       <span class="c1">// プロダクトイベントログを取得して送信</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><strong>組み合わせて使用：</strong></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">sender</span> <span class="o">=</span> <span class="kt">TrackingEventSender</span><span class="p">()</span>
<span class="n">sender</span><span class="o">.</span><span class="nf">register</span><span class="p">(</span><span class="nv">event</span><span class="p">:</span> <span class="kt">HomeTrackingHandlerStrategy</span><span class="p">())</span>
<span class="n">sender</span><span class="o">.</span><span class="nf">register</span><span class="p">(</span><span class="nv">event</span><span class="p">:</span> <span class="kt">ProductTrackingHandlerStrategy</span><span class="p">())</span>
<span class="n">sender</span><span class="o">.</span><span class="nf">startTracking</span><span class="p">()</span>

<span class="c1">// ...</span>

<span class="c1">//</span>

<span class="kd">final</span> <span class="kd">class</span> <span class="kt">TrackingEventSender</span> <span class="p">{</span>

    <span class="kd">private</span> <span class="k">let</span> <span class="nv">timerMachine</span> <span class="o">=</span> <span class="kt">DispatchSourceTimerMachine</span><span class="p">()</span>
    <span class="kd">private</span> <span class="k">var</span> <span class="nv">events</span><span class="p">:</span> <span class="p">[</span><span class="kt">String</span><span class="p">:</span> <span class="kt">TrackingHandlerStrategy</span><span class="p">]</span> <span class="o">=</span> <span class="p">[:]</span>

    <span class="c1">// 必要なイベント戦略を登録する</span>
    <span class="kd">func</span> <span class="nf">register</span><span class="p">(</span><span class="nv">event</span><span class="p">:</span> <span class="kt">TrackingHandlerStrategy</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">events</span><span class="p">[</span><span class="nf">type</span><span class="p">(</span><span class="nv">of</span><span class="p">:</span> <span class="n">event</span><span class="p">)</span><span class="o">.</span><span class="n">target</span><span class="p">]</span> <span class="o">=</span> <span class="n">event</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="n">retrive</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">TrackingHandlerStrategy</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">event</span><span class="p">:</span> <span class="kt">T</span><span class="o">.</span><span class="k">Type</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">T</span><span class="p">?</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">events</span><span class="p">[</span><span class="n">event</span><span class="o">.</span><span class="n">target</span><span class="p">]</span> <span class="k">as?</span> <span class="kt">T</span>
    <span class="p">}</span>

    <span class="c1">// 定期トラッキングを開始する</span>
    <span class="kd">func</span> <span class="nf">startTracking</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">timerMachine</span><span class="o">.</span><span class="nf">activate</span><span class="p">(</span><span class="nv">repeatTimeInterval</span><span class="p">:</span> <span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">30</span><span class="p">))</span> <span class="p">{</span> <span class="p">[</span><span class="k">weak</span> <span class="k">self</span><span class="p">]</span> <span class="k">in</span>
            <span class="k">self</span><span class="p">?</span><span class="o">.</span><span class="n">events</span><span class="o">.</span><span class="n">values</span><span class="o">.</span><span class="n">forEach</span> <span class="p">{</span> <span class="n">event</span> <span class="k">in</span>
                <span class="n">event</span><span class="o">.</span><span class="nf">execute</span><span class="p">()</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// トラッキングを一時停止する（例：アプリがバックグラウンドに入る時）</span>
    <span class="kd">func</span> <span class="nf">pauseTracking</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">timerMachine</span><span class="o">.</span><span class="nf">suspend</span><span class="p">()</span>
    <span class="p">}</span>

    <span class="c1">// トラッキングを再開する（例：アプリがフォアグラウンドに戻る時）</span>
    <span class="kd">func</span> <span class="nf">resumeTracking</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">timerMachine</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
    <span class="p">}</span>

    <span class="c1">// トラッキングを停止する（例：画面を離れる時）</span>
    <span class="kd">func</span> <span class="nf">stopTracking</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">timerMachine</span><span class="o">.</span><span class="nf">cancel</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="謝辞">謝辞</h4>

<p>感謝 <a href="https://medium.com/u/e13f6afcf9b9" target="_blank">Ethan Huang</a> さんの <strong>5本のビール</strong> の寄付：</p>

<p><a href="https://www.patreon.com/cw/ethanhuang13/home?vanity=ethanhuang13" target="_blank"><img src="https://c7.patreon.com/https%3A%2F%2Fwww.patreon.com%2F%2Fcard-teaser-image%2Fcreator%2F6512681%3Fc=6796995314395033145/selector/%23creator-teaser%2C.png" alt="" /></a></p>

<blockquote>
  <p><em>確かにもう半年ほど何も書いていません。新しい仕事に就いたばかりで、引き続きインスピレーションを探しています！💪</em></p>
</blockquote>

<blockquote>
  <p>次回は Fastlane Match の証明書管理や Self-hosted Runner の構築手順、あるいは Bitbucket Pipeline、または AppStoreConnect API について共有するかもしれません…</p>
</blockquote>

<h3 id="関連記事">関連記事</h3>

<ul>
  <li>
    <p><a href="/posts/pinkoiエンジニアリング/design-patterns-socket-io-client封裝で直面した課題と実践的解決策-78507a8de6a5/"><strong>Design Patterns の実践応用記録 (Socket.io のラップ)</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/kkdayテックブログ/wkwebviewのdesign-patterns実践-builder-strategy-chain-of-responsibilityで効率開発-f4b02ee342a4/">Design Patterns の実践応用記録 (WKWebViewのラップ)</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm開発/visitor-pattern-ios-swiftでの設計パターン活用法と実践例-ba5773a7bfea/">Swiftにおけるビジターパターン</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm開発/visitor-pattern-tableviewの可読性と拡張性を劇的に向上させる方法-60473cb47550/">TableViewにおけるビジターパターン</a></p>
  </li>
</ul>

<p><em><a href="https://medium.com/zrealm-ios-dev/ios-timer-%E8%88%87-dispatchsourcetimer-%E5%A6%82%E4%BD%95%E9%81%B8%E6%93%87%E8%88%87%E5%AE%89%E5%85%A8%E7%9A%84%E4%BD%BF%E7%94%A8-62f68ebeecd3" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>を使って変換しました。</em></p>]]></content>
  </entry><entry>
    <title type="html">日本海外購物：樂天集運で楽天＆Amazon商品を台湾へスムーズ配送｜Horie鈦杯購入ガイド</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-life/%E6%97%A5%E6%9C%AC%E6%B5%B7%E5%A4%96%E8%B3%BC%E7%89%A9-%E6%A8%82%E5%A4%A9%E9%9B%86%E9%81%8B%E3%81%A7%E6%A5%BD%E5%A4%A9-amazon%E5%95%86%E5%93%81%E3%82%92%E5%8F%B0%E6%B9%BE%E3%81%B8%E3%82%B9%E3%83%A0%E3%83%BC%E3%82%BA%E9%85%8D%E9%80%81-horie%E9%88%A6%E6%9D%AF%E8%B3%BC%E5%85%A5%E3%82%AC%E3%82%A4%E3%83%89-bea62c251f1b/" rel="alternate" type="text/html" title="日本海外購物：樂天集運で楽天＆Amazon商品を台湾へスムーズ配送｜Horie鈦杯購入ガイド" />
    <published>2025-10-26T17:58:35+08:00</published>
    <updated>2025-10-27T08:41:53+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-life/bea62c251f1b</id><summary type="html">台湾在住者向けに、楽天集運を利用して楽天やAmazonから日本商品を安全かつ迅速に購入・配送する方法を解説。Horie鈦杯の実例で具体的な手順と注意点を紹介し、海外通販の不安を解消します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm Life." /><category term="生活" /><category term="開封" /><category term="楽天" /><category term="チタンカップ" /><category term="集荷" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/bea62c251f1b/1*bXj9-XVgjfsVta6cZg8Fpw.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-life/%E6%97%A5%E6%9C%AC%E6%B5%B7%E5%A4%96%E8%B3%BC%E7%89%A9-%E6%A8%82%E5%A4%A9%E9%9B%86%E9%81%8B%E3%81%A7%E6%A5%BD%E5%A4%A9-amazon%E5%95%86%E5%93%81%E3%82%92%E5%8F%B0%E6%B9%BE%E3%81%B8%E3%82%B9%E3%83%A0%E3%83%BC%E3%82%BA%E9%85%8D%E9%80%81-horie%E9%88%A6%E6%9D%AF%E8%B3%BC%E5%85%A5%E3%82%AC%E3%82%A4%E3%83%89-bea62c251f1b/"><![CDATA[<h3 id="日本から台湾への海外通販配送ガイド--楽天転送を使って楽天市場とamazonの商品horieチタンカップを購入最短4日で到着">日本から台湾への海外通販配送ガイド — 楽天転送を使って楽天市場とAmazonの商品（Horieチタンカップ）を購入、最短4日で到着</h3>

<p>欲しいものは自分で買う！楽天転送を使って日本の商品を台湾へ送る記録と方法〜Horieチタンカップ購入例〜</p>

<h3 id="horie-チタンカップ"><a href="https://a.r10.to/hkPx9m" target="_blank">Horie チタンカップ</a></h3>

<p>前回日本で火傷した経験から、Horieチタンカップの主な特徴：</p>

<p><img src="/assets/bea62c251f1b/1*7m-tH8lB3Sx0yxtdc9Bn_g.webp" alt="公式 Horie 楽天ショップ" loading="lazy" decoding="async" width="776" height="970" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzYiIGhlaWdodD0iOTcwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*7m-tH8lB3Sx0yxtdc9Bn_g.png" /></p>

<p><a href="https://a.r10.to/hkPx9m" target="_blank">公式 Horie 楽天ショップ</a></p>

<ul>
  <li>
    <p>独自の酸化着色技術により、鮮やかで多彩な色合いが選べます</p>
  </li>
  <li>
    <p>独自の二重断熱構造で、冷たさを保ち結露せず、温かさを保っても熱くなりません</p>
  </li>
  <li>
    <p>独自の特殊な内側カップデザインにより、ビールを飲むときに持続するきめ細かい泡が自動的に生成されます</p>
  </li>
  <li>
    <p>飲み口が狭く、口を傷つけません</p>
  </li>
  <li>
    <p>純チタン素材で非常に軽く、抗菌性があり、臭いも残りません</p>
  </li>
</ul>

<p>私が最も惹かれたのは最初の三つの独自技術 <strong>＋それが保温ボトルであること</strong> です。しかも、今は鈦製のボトルを持っておらず、保温ボトルの匂いが残りやすい問題にも悩んでいるので、ぜひ一つ買って使ってみたいと思いました。</p>

<h4 id="購入したい商品"><strong>購入したい商品：</strong></h4>

<blockquote>
  <p><em>ブランド：Horie チタンカップ</em></p>
</blockquote>

<blockquote>
  <p><em>型番：窯創り ブースター/400ml</em></p>
</blockquote>

<blockquote>
  <p><em>スタイル：G4B</em></p>
</blockquote>

<p><a href="https://a.r10.to/hkPx9m" target="_blank">公式価格</a> <strong>19,800円（約NT$4,080）</strong>、日本国内送料無料。</p>

<p>台湾での購入を調べたところ、ECプラットフォームや個人売買問わず、価格は約NT$5,500前後です。時折、団体購入や展示会のイベントでNT$4,200前後まで値下げされることがあり、その時が購入のチャンスです。</p>

<h3 id="楽天転送で台湾へ配送する際の総所要時間と費用">楽天転送で台湾へ配送する際の総所要時間と費用</h3>

<p>結果を先に述べます。</p>

<p><img src="/assets/bea62c251f1b/1*n3ahp0WYgvO36vendy3GEQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="569" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU2OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*n3ahp0WYgvO36vendy3GEQ.png" /></p>

<ul>
  <li>
    <p>刻印があるため、製作に7～10日かかりました。また、雑誌も購入したため、雑誌が楽天転送に届くまでに時間がかかりました。</p>
  </li>
  <li>
    <p>単純に転送時間を見ると、転送センターが荷物を受け取ってからわずか1日、梱包から発送、受け取りまでわずか3日で、とても速いと言えます！</p>
  </li>
  <li>
    <p>合計費用（送料込み）：NT$4,744で購入しました。（詳細は本文をご覧ください。購入数が少ないため送料が高くなりました）</p>
  </li>
</ul>

<h3 id="楽天グローバルエクスプレス--rakuten-global-express"><a href="https://secure.globalexpress.rakuten.co.jp/mypage/register/invite?key=a6nn9r3fq6j4sskcsOrXE%2Bgdygp0zER%2FMe83%2FUDPw6k7LFkMFZBfgN0hX48E%3D" target="_blank">楽天グローバルエクスプレス — Rakuten Global Express</a></h3>

<p>せっかく日本の楽天市場で買い物をするなら、楽天の転送・集荷サービスを試してみようと思いました。もちろん楽天転送は楽天の商品だけでなく、他のECサイト、例えば日本のAmazon（Amazon JP）、日本のYahooショッピング／Yahooオークション、メルカリ、ビックカメラなども利用可能です。</p>

<ul>
  <li>楽天ポイントを貯められ、ポイントでの支払いも可能です！</li>
</ul>

<h4 id="楽天転送を使って楽天商品を購入する際の特別保証">楽天転送を使って楽天商品を購入する際の特別保証</h4>

<p>転送・集荷サービスを提供するだけでなく、<strong>楽天の転送サービスを利用して楽天市場の商品を購入する場合</strong>、以下の追加保証も提供されます：</p>

<ul>
  <li>
    <p>補償サービス：支払い済みだが商品が届かない場合</p>
  </li>
  <li>
    <p>補償サービス：商品破損（物流会社発行の破損報告書を取得してください）</p>
  </li>
  <li>
    <p>補償サービス：商品ページの説明と明らかに異なる商品や不良品を受け取った場合</p>
  </li>
  <li>
    <p>補償サービス：受け取ったブランド商品が偽物であり、商標権を侵害する商品である場合（安心ショッピング保証対象の1,000以上のブランド）</p>
  </li>
  <li>
    <p>賠償金額：上限は30万円</p>
  </li>
  <li>
    <p>手数料や年会費は不要です</p>
  </li>
</ul>

<p>詳細は<a href="https://event.rakuten.co.jp/anshin/anshinshopping/zh-tw/top/" target="_blank">公式説明</a>をご参照ください。</p>

<h4 id="楽天以外の購入保証">楽天以外の購入保証</h4>

<p>楽天市場以外で購入した商品には、基本的な転送配送保障が提供されます：</p>

<ul>
  <li>
    <p>補償サービス：支払い済みだが商品が届かない場合</p>
  </li>
  <li>
    <p>補償サービス：商品破損（物流会社発行の破損報告書を取得してください）</p>
  </li>
</ul>

<p>詳細は<a href="https://globalexpress.rakuten.co.jp/help/insurance?l-id=help_tw_insurance" target="_blank">公式説明</a>をご参照ください。</p>

<h4 id="送料計算見積もり">送料計算、見積もり</h4>

<p><a href="https://globalexpress.rakuten.co.jp/estimate/?l-id=top_estimate" target="_blank">公式ツール</a> を使って転送送料を見積もることができます。</p>

<p><img src="/assets/bea62c251f1b/1*4mfK-p6n2FUgWpDCq8xisQ.webp" alt="&lt;https://globalexpress.rakuten.co.jp/estimate/?l-id=top_estimate&gt;" loading="lazy" decoding="async" width="949" height="596" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDkiIGhlaWdodD0iNTk2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*4mfK-p6n2FUgWpDCq8xisQ.png" /></p>

<p><a href="https://globalexpress.rakuten.co.jp/estimate/?l-id=top_estimate" target="_blank">https://globalexpress.rakuten.co.jp/estimate/?l-id=top_estimate</a></p>

<p><strong>配送方法と台湾送料表</strong></p>

<p><img src="/assets/bea62c251f1b/1*Bi9oS0C32l8Mhvtwfdg-zg.webp" alt="&lt;https://globalexpress.rakuten.co.jp/help/delivery&gt;" loading="lazy" decoding="async" width="947" height="670" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDciIGhlaWdodD0iNjcwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*Bi9oS0C32l8Mhvtwfdg-zg.png" /></p>

<p><a href="https://globalexpress.rakuten.co.jp/help/delivery" target="_blank">https://globalexpress.rakuten.co.jp/help/delivery</a></p>

<p><img src="/assets/bea62c251f1b/1*k4M0QBRRDbPQZ7BSyB6c4A.webp" alt="&lt;https://globalexpress.rakuten.co.jp/help/country/fee?country=TW&gt;" loading="lazy" decoding="async" width="980" height="943" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5ODAiIGhlaWdodD0iOTQzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*k4M0QBRRDbPQZ7BSyB6c4A.png" /></p>

<p><a href="https://globalexpress.rakuten.co.jp/help/country/fee?country=TW" target="_blank">https://globalexpress.rakuten.co.jp/help/country/fee?country=TW</a></p>

<blockquote>
  <p><em>ここでのサイズと重量は、最終的な集荷後の数値です。</em></p>
</blockquote>

<h3 id="日本楽天アカウント登録">日本楽天アカウント登録</h3>

<p><a href="https://login.account.rakuten.com/sso/register?client_id=rakuten_ichiba_top_web&amp;service_id=s245&amp;response_type=code&amp;scope=openid&amp;redirect_uri=https%3A%2F%2Fwww.rakuten.co.jp%2F#/registration/1" target="_blank"><strong>登録ページ</strong></a> へ進みます：</p>

<p><img src="/assets/bea62c251f1b/1*b3acAhAfqIrsIe7-hHuQLA.webp" alt="" loading="lazy" decoding="async" width="1307" height="1467" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzA3IiBoZWlnaHQ9IjE0NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/bea62c251f1b/1*b3acAhAfqIrsIe7-hHuQLA.png" /></p>

<p>メールアドレス、パスワード、英語の名前を入力し、送信すると登録が完了します。</p>

<blockquote>
  <p><em>こちらでランダムなサイトの問題を発見しました。<strong>楽天サイトでサーバーエラーが繰り返し表示される場合は、言語設定を日本語に変更すると</strong>正常に利用できます。（多言語対応のエラーの可能性があります）</em></p>
</blockquote>

<h4 id="まず楽天転送で本人確認を完了させる">まず楽天転送で本人確認を完了させる</h4>

<p><img src="/assets/bea62c251f1b/1*roub7uHzS2bUtIP5qIg8pA.webp" alt="" loading="lazy" decoding="async" width="1330" height="920" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzMwIiBoZWlnaHQ9IjkyMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*roub7uHzS2bUtIP5qIg8pA.png" /></p>

<p>楽天に登録後、<a href="https://secure.globalexpress.rakuten.co.jp/mypage/register/invite?key=aanar03e62e0ckog4nWPIFcV7FTuy6JGEeCL1HwxrPgcSjKRlGHs1GY6PkH0%3D" target="_blank">楽天転送</a> にアクセスすると、デフォルトでログイン状態になっています。</p>

<ol>
  <li>
    <p>まず、操作を簡単にするために言語を繁体字中国語に変更してください。</p>
  </li>
  <li>
    <p>マイページをクリックして転送サービスを開始する</p>
  </li>
</ol>

<p><img src="/assets/bea62c251f1b/1*LtS88oCvn5XKCHImq_8Twg.webp" alt="" loading="lazy" decoding="async" width="537" height="715" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MzciIGhlaWdodD0iNzE1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*LtS88oCvn5XKCHImq_8Twg.png" /></p>

<p><img src="/assets/bea62c251f1b/1*EBb5vLI574judf0zb4up9Q.webp" alt="" loading="lazy" decoding="async" width="522" height="701" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MjIiIGhlaWdodD0iNzAxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*EBb5vLI574judf0zb4up9Q.png" /></p>

<p>メールボックスにアクセスして認証コードを受け取り、メール認証を完了してください。</p>

<p><img src="/assets/bea62c251f1b/1*caABYLKqpF995bAS9QULpQ.webp" alt="" loading="lazy" decoding="async" width="530" height="692" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MzAiIGhlaWdodD0iNjkyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*caABYLKqpF995bAS9QULpQ.png" /></p>

<p>次に、名前情報を入力します。</p>

<ul>
  <li>
    <p>姓（漢字）、名（漢字）：中国語の名前を記入してください</p>
  </li>
  <li>
    <p>姓（カタカナ）、名（カタカナ）：名前をカタカナで入力してください。<a href="https://dokochina.com/katakana.php" target="_blank">こちらのサイト</a>で変換できます。またはニックネームでも構いません。例：リー、ハリー。</p>
  </li>
</ul>

<h4 id="楽天転送住所の開設と本人確認の完了">楽天転送住所の開設と本人確認の完了</h4>

<p><img src="/assets/bea62c251f1b/1*XH92Vc8EmKSvvF3RH7hYJg.webp" alt="" loading="lazy" decoding="async" width="1200" height="716" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjcxNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*XH92Vc8EmKSvvF3RH7hYJg.png" /></p>

<p>第一歩として利用規約に同意します。<strong>一部の商品（可燃物、スプレー、生鮮食品など）は発送禁止です</strong>。</p>

<p><img src="/assets/bea62c251f1b/1*WOxQ8TpaXdOS_BJqyWeZYg.webp" alt="" loading="lazy" decoding="async" width="892" height="1109" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4OTIiIGhlaWdodD0iMTEwOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*WOxQ8TpaXdOS_BJqyWeZYg.png" /></p>

<p>第二ステップで本人情報を入力します。必ずパスポートの英語表記の名前と生年月日を正確に入力してください。</p>

<h4 id="専用の楽天転送住所を取得する">専用の楽天転送住所を取得する</h4>

<p><img src="/assets/bea62c251f1b/1*u8ObmbBY2rsVw93cS8ADDA.webp" alt="" loading="lazy" decoding="async" width="880" height="1180" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4ODAiIGhlaWdodD0iMTE4MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*u8ObmbBY2rsVw93cS8ADDA.png" /></p>

<ul>
  <li>
    <p>転送倉庫の住所は必ず最後の <code class="language-plaintext highlighter-rouge">白石町6–1 RGXセンター XXXXXXX</code> の英数字番号まで入力してください。これがあなた専用の識別住所です。</p>
  </li>
  <li>
    <p>「今すぐ追加」をクリックすると、住所を直接楽天アカウントに追加できます。</p>
  </li>
</ul>

<blockquote>
  <p><em>この住所と電話番号があれば、日本の主要なECサイトで購入し、発送が可能です！ただし、転送を安全に受け取るために、<strong>「本人認証手続きを完了してから」購入・発送してください。</strong></em></p>
</blockquote>

<h4 id="本人認証手続きを続ける">本人認証手続きを続ける</h4>

<p><img src="/assets/bea62c251f1b/1*Fv2V7TPlqTBQHTeo3bPuWg.webp" alt="" loading="lazy" decoding="async" width="860" height="941" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjAiIGhlaWdodD0iOTQxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*Fv2V7TPlqTBQHTeo3bPuWg.png" /></p>

<ul>
  <li>身分証の原本と携帯電話を準備し、顔認証で認証を行うことで、オンラインで24時間いつでもセルフ認証手続きを完了できます。</li>
</ul>

<blockquote>
  <p><em>しかし、私の身分証の写真が本人とかなり違っていたため、オンライン認証に失敗し、自動で手動審査に切り替わり、翌日ようやく公式から手動審査完了の通知が届きました。</em></p>
</blockquote>

<h4 id="マイページ">マイページ</h4>

<p>上部の「マイページ」または「マイページトップ」をクリックして、マイページのホームに移動します：</p>

<p><img src="/assets/bea62c251f1b/1*MhXfS0YfDj4TVZC_h1uBmA.webp" alt="" loading="lazy" decoding="async" width="950" height="584" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTAiIGhlaWdodD0iNTg0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*MhXfS0YfDj4TVZC_h1uBmA.png" /></p>

<p><img src="/assets/bea62c251f1b/1*_qPCZpRDpfbrNfytEsjBGA.webp" alt="" loading="lazy" decoding="async" width="1322" height="596" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzIyIiBoZWlnaHQ9IjU5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*_qPCZpRDpfbrNfytEsjBGA.png" /></p>

<p>認証手続きが完了していない場合、以下の警告メッセージが表示されます：</p>

<p><img src="/assets/bea62c251f1b/1*qkgvVofPd8uI6CLH_0rnhw.webp" alt="" loading="lazy" decoding="async" width="694" height="200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2OTQiIGhlaWdodD0iMjAwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*qkgvVofPd8uI6CLH_0rnhw.png" /></p>

<blockquote>
  <p><strong><em>必ず認証を完了してから購入してください。</em></strong></p>
</blockquote>

<h4 id="あなた専用の受取住所と情報">あなた専用の受取住所と情報</h4>

<p>私のページの右下にあなた専用の情報が表示されます。</p>

<p><img src="/assets/bea62c251f1b/1*_qsR1A94i83sEDAVpGxgbg.webp" alt="" loading="lazy" decoding="async" width="1313" height="1083" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzEzIiBoZWlnaHQ9IjEwODMiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/bea62c251f1b/1*_qsR1A94i83sEDAVpGxgbg.png" /></p>

<h3 id="台湾への発送禁止品目">台湾への発送禁止品目</h3>

<p>購入した商品を台湾に送る際は、禁止品目でないか必ず確認してください。</p>

<p><img src="/assets/bea62c251f1b/1*c7qamfTN89ipGwM9LZUblQ.webp" alt="&lt;https://globalexpress.rakuten.co.jp/help/country/detail?country=TW&gt;" loading="lazy" decoding="async" width="959" height="873" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTkiIGhlaWdodD0iODczIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*c7qamfTN89ipGwM9LZUblQ.png" /></p>

<p><a href="https://globalexpress.rakuten.co.jp/help/country/detail?country=TW" target="_blank">https://globalexpress.rakuten.co.jp/help/country/detail?country=TW</a></p>

<p>配送方法によって制限が異なりますので、<a href="https://globalexpress.rakuten.co.jp/help/country/detail?country=TW" target="_blank">必ずご確認ください</a> 。</p>

<blockquote>
  <p><em>お酒やタバコなどを購入する場合は、必ず事前に他の人の解説をネットで調べてください。大まかに言うと、台湾に送った後に通知書を持って税金を追加で支払わないと通関できないようです。</em></p>
</blockquote>

<h3 id="楽天市場での購入--horie-チタンカップ-注文ガイド"><a href="https://a.r10.to/hkPx9m" target="_blank">楽天市場での購入 — Horie チタンカップ</a> 注文ガイド</h3>

<blockquote>
  <p><em>1055℃の窯で作られた高保冷チタン二重タンブラー。アレルギーフリーで清潔、錆びずに軽くて丈夫で長持ちします。大切な方への贈り物や自分へのご褒美に最適です。【無料ラッピング対応】HORIE公式ショップ／窯作り 名入れ 純チタン製二重タンブラー horie チタンタンブラー 母の日 父の日 敬老の日 ギフト ビールグラス ホリエ 燕三条 誕生日プレゼント お餞別 退職祝い 内祝い 結婚祝い SDGs クリスマス</em></p>
</blockquote>

<blockquote>
  <p><em>13,200〜19,800円送料無料</em></p>
</blockquote>

<h4 id="商品ページへ-"><a href="https://a.r10.to/hkPx9m" target="_blank">商品ページへ</a> ：</h4>

<p><img src="/assets/bea62c251f1b/1*8aYksm9WZ5UUkmSKSI_5EA.webp" alt="商品ページ" loading="lazy" decoding="async" width="938" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzgiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*8aYksm9WZ5UUkmSKSI_5EA.png" /></p>

<p><a href="https://a.r10.to/hkPx9m" target="_blank">商品ページ</a></p>

<p>これは窯創シリーズの商品ページです。別のシリーズを選びたい場合は、<a href="https://a.r10.to/hkG3CK" target="_blank">HORIEショップのトップページ</a>をクリックしてください。</p>

<p>一番下までスクロールして商品詳細を選択してください（商品詳細を選択）。</p>

<ul>
  <li>
    <p><strong>形状/サイズ</strong> ：お好みのスタイルを選んでください（商品ページの画像をご覧ください。広口、狭口、容量の違いがあります）</p>
  </li>
  <li>
    <p><strong>カラー</strong> ：希望するスタイルを選んでください（商品ページの画像をご覧ください）</p>
  </li>
</ul>

<p><strong>私が購入したのは：窯創り ブースター/400ml &amp; G4B：</strong></p>

<p><img src="/assets/bea62c251f1b/1*rwCNpways8AGJZ3DglI0qw.webp" alt="" loading="lazy" decoding="async" width="727" height="1016" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MjciIGhlaWdodD0iMTAxNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*rwCNpways8AGJZ3DglI0qw.png" /></p>

<p><strong>名入れオプション</strong> ：刻印を希望するかどうか（オンラインストア限定、<strong>無料刻印</strong>）、7〜10営業日かかります：</p>

<p><img src="/assets/bea62c251f1b/1*8Zfq6b9q2X2jORa51cjm1w.webp" alt="" loading="lazy" decoding="async" width="657" height="825" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NTciIGhlaWdodD0iODI1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*8Zfq6b9q2X2jORa51cjm1w.png" /></p>

<p><strong>ラッピングの有無</strong> ：包装紙のスタイル、AまたはBまたはなし。</p>

<p><img src="/assets/bea62c251f1b/1*TeJNyUkr6nsAapTC9H504A.webp" alt="" loading="lazy" decoding="async" width="640" height="623" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NDAiIGhlaWdodD0iNjIzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*TeJNyUkr6nsAapTC9H504A.png" /></p>

<p><strong>桐箱デザインの選択</strong> ：包装箱のスタイル、WakuWaku驚き版（左、単品限定）または一般版（右）</p>

<p><strong>2個セット用桐箱 (※2個以上ご注文・必要な場合のみチェックを入れる)：</strong> 2個以上購入する場合にチェックを入れ、<strong>同じ箱に入れる</strong>（下図右下参照）。
1個だけ購入の場合はスキップしてください。</p>

<p><strong>2個セットの場合の組み合わせ（記入例：プレミアムとライト）（※2セット以上ご注文の場合は必ず明記）：</strong> 2セット以上購入する場合の箱の組み合わせ方法です。面倒な場合は、別々にカートに入れる方が早いです。<br />
1個だけ購入する場合は省略できます。</p>

<p><img src="/assets/bea62c251f1b/1*49fEtjiRRBvNyEGxdFeE3A.webp" alt="" loading="lazy" decoding="async" width="645" height="621" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NDUiIGhlaWdodD0iNjIxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*49fEtjiRRBvNyEGxdFeE3A.png" /></p>

<p><strong>名入れタイプ※単品名入れ商品を2個以上ご注文の場合は、お手数ですが1個ずつ買い物かごに入れてください：</strong> 名入れ不要（刻印不要）の場合は以下の欄をスキップしてください。刻印する場合は商品ページの画像情報に従い、スタイルを選択し各行の文字を入力してください：</p>

<ul>
  <li>
    <p><strong>名入れ1行目</strong></p>
  </li>
  <li>
    <p><strong>名入れ2行目</strong></p>
  </li>
  <li>
    <p><strong>名入れ3行目</strong></p>
  </li>
  <li>
    <p><strong>名入れ4行目</strong></p>
  </li>
</ul>

<blockquote>
  <p><strong><em>刻印を希望する場合は、刻印内容を一文字ずつ別々にカートに入れてください。</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>私はBスタイルの刻印を選びました（文末に写真があります）。</em></strong></p>
</blockquote>

<p><img src="/assets/bea62c251f1b/1*i50V97FHogvQ4PVCFTLX7Q.webp" alt="" loading="lazy" decoding="async" width="625" height="630" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MjUiIGhlaWdodD0iNjMwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*i50V97FHogvQ4PVCFTLX7Q.png" /></p>

<p><strong>ギフト包装とメッセージカードのデザイン・内容：</strong></p>

<ul>
  <li>
    <p>のしの内容：のしの種類（例：御祝、祝寿など）、不要な場合は「のし不要」を選択してください。</p>
  </li>
  <li>
    <p>のしの種類：のしのスタイルは以下の画像の通りです。不要な場合は「のし不要」を選択してください。</p>
  </li>
  <li>
    <p>のしの水引きの種類：のしの結び方のスタイルは以下の図の通りです。不要な場合は「のし不要」を選んでください。</p>
  </li>
</ul>

<p><img src="/assets/bea62c251f1b/1*uLCkqmso0Ad9MTynZL0T-w.webp" alt="" loading="lazy" decoding="async" width="626" height="854" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MjYiIGhlaWdodD0iODU0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*uLCkqmso0Ad9MTynZL0T-w.png" /></p>

<p><strong>のしに記入するお名前(贈り主)※連名の場合は間に・を入力。内祝い等でふりがなをご希望の際はふりがなもご入力ください。20文字以上の場合は備考欄にお願いします：</strong> のし（熨斗）に印刷する贈り主の名前を入力してください。複数名の場合は名前の間に「・」を入れてください。不要な場合は空欄のままにしてください。</p>

<h4 id="カートに入れて注文を完了する">カートに入れて、注文を完了する</h4>

<p><img src="/assets/bea62c251f1b/1*UCbosHBXeND4C0Q7hoX38A.webp" alt="" loading="lazy" decoding="async" width="627" height="711" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MjciIGhlaWdodD0iNzExIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*UCbosHBXeND4C0Q7hoX38A.png" /></p>

<p>規格内容をすべて入力したら「かごに追加」をクリックしてカートに入れ、お届け先の受取人情報は楽天転送の「神奈川県」を選択します。下に楽天転送への配送予定時間や送料無料の表示も出ます。すべて入力が終わったら、上のカートからチェックアウトをクリックします：</p>

<p><img src="/assets/bea62c251f1b/1*XP6gv2xNgplYY_IvQyKNCQ.webp" alt="" loading="lazy" decoding="async" width="1048" height="615" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDQ4IiBoZWlnaHQ9IjYxNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*XP6gv2xNgplYY_IvQyKNCQ.png" /></p>

<p>商品仕様に間違いがないことを確認したら、右側の「購入手続き」をクリックしてください。</p>

<p><img src="/assets/bea62c251f1b/1*lsPBGTQGkyJ_RAG0VjayAw.webp" alt="" loading="lazy" decoding="async" width="1049" height="989" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDQ5IiBoZWlnaHQ9Ijk4OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*lsPBGTQGkyJ_RAG0VjayAw.png" /></p>

<ul>
  <li>
    <p><strong>お届け先：</strong> 配送先情報は、楽天転送で新たに追加した転送先住所を直接選択するか、自分で転送先住所を追加してください（転送先住所は最後の番号まで必ず入力してください）。</p>
  </li>
  <li>
    <p><strong>支払い方法：</strong> 支払い方法はクレジットカードを直接使用しました（日本での購入なので、どの銀行がキャンペーンをしているか確認できます）。</p>
  </li>
</ul>

<p>問題がなければ「注文を確定する」をクリックして注文を完了してください。</p>

<h4 id="horie-刻印確認">HORIE 刻印確認</h4>

<p><img src="/assets/bea62c251f1b/1*Q8t3tiej00RrQqsEBVsOLg.webp" alt="" loading="lazy" decoding="async" width="921" height="1190" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjEiIGhlaWdodD0iMTE5MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*Q8t3tiej00RrQqsEBVsOLg.png" /></p>

<p>刻印を選択した場合、HORIEは注文後に確認結果を送信します。問題なければ「ご送付いただいたレイアウトを確認しました。問題ございませんので製作を進めてください。」と返信して製作を開始してもらいましょう。</p>

<p>発送時間もメッセージで知らせてくれます。</p>

<h4 id="出荷通知および楽天転送到着通知">出荷通知および楽天転送到着通知</h4>

<p><img src="/assets/bea62c251f1b/1*DGN-R9yxdnrjEMlSR5W0Bw.webp" alt="" loading="lazy" decoding="async" width="850" height="761" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NTAiIGhlaWdodD0iNzYxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*DGN-R9yxdnrjEMlSR5W0Bw.png" /></p>

<p><img src="/assets/bea62c251f1b/1*j5pKRcNpLfuiToRzoNG-bg.webp" alt="" loading="lazy" decoding="async" width="894" height="642" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4OTQiIGhlaWdodD0iNjQyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*j5pKRcNpLfuiToRzoNG-bg.png" /></p>

<p>HORIEからの発送通知を受け取ってから約1〜3日で楽天転送倉庫に届きました。</p>

<h3 id="日本のamazon-jpから楽天転送への発送方法">日本のAmazon JPから楽天転送への発送方法</h3>

<p>今回はHORIEのチタンカップのほかに、日本のAmazon JPで雑誌も購入し、一緒に転送して台湾へ送る予定です。</p>

<p><img src="/assets/bea62c251f1b/1*70bmfM40fgui1EptFuLylA.webp" alt="" loading="lazy" decoding="async" width="1400" height="707" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjcwNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*70bmfM40fgui1EptFuLylA.png" /></p>

<p>ショッピングサイトでの操作は同じですが、必ず楽天転送の受取情報にある配送先住所と連絡先電話番号（転送サービスの番号）を入力してください。</p>

<h4 id="楽天市場以外の購入荷物到着事前登録">（楽天市場以外の購入）荷物到着事前登録</h4>

<p>楽天本家以外で購入した商品を転送先に送る場合は、注文後に登録することをおすすめします。</p>

<p><img src="/assets/bea62c251f1b/1*hbc4AK4PyGSScxgg8Q9OWg.webp" alt="" loading="lazy" decoding="async" width="1217" height="716" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjE3IiBoZWlnaHQ9IjcxNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*hbc4AK4PyGSScxgg8Q9OWg.png" /></p>

<p>「貨物一覧表」→「登録/確認」をクリックしてください</p>

<p><img src="/assets/bea62c251f1b/1*IYs0xH6f-y55OFHDGmWpHQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="574" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjU3NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*IYs0xH6f-y55OFHDGmWpHQ.png" /></p>

<p>他のプラットフォームで購入した店舗、商品情報、金額を入力してください。</p>

<h4 id="日本のamazon-jpでの商品購入---楽天転送の到着通知">日本のAmazon JPでの商品購入 - 楽天転送の到着通知</h4>

<p><img src="/assets/bea62c251f1b/1*eWxfcNY_Wsr7VT9-5ZuFtQ.webp" alt="" loading="lazy" decoding="async" width="610" height="437" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MTAiIGhlaWdodD0iNDM3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*eWxfcNY_Wsr7VT9-5ZuFtQ.png" /></p>

<p>すべて完了したら、販売者の発送を待ち、商品が楽天転送に到着すると通知が届きます。</p>

<h3 id="楽天転送で台湾へ配送">楽天転送で台湾へ配送</h3>

<p><a href="https://globalexpress.rakuten.co.jp/faq/detail?id=99" target="_blank">楽天転送は最長30日間無料で荷物を保管できます</a>。荷物がすべて届き、まとめられたら、梱包発送を依頼できます。</p>

<p><img src="/assets/bea62c251f1b/1*m3TCoxNu_7ltuthkRAXFBg.webp" alt="" loading="lazy" decoding="async" width="1200" height="663" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY2MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*m3TCoxNu_7ltuthkRAXFBg.png" /></p>

<p>届いた商品：合計3点。</p>

<p>「貨物一覧表」をクリック：</p>

<p><img src="/assets/bea62c251f1b/1*4YRX_1LsNWvrExJAeoQ0nQ.webp" alt="" loading="lazy" decoding="async" width="795" height="831" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3OTUiIGhlaWdodD0iODMxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*4YRX_1LsNWvrExJAeoQ0nQ.png" /></p>

<p>「梱包依頼を提出する」をクリックしてください</p>

<p><img src="/assets/bea62c251f1b/1*gUgWUivN-7jH9wNcFn-Y6g.webp" alt="" loading="lazy" decoding="async" width="1400" height="637" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjYzNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*gUgWUivN-7jH9wNcFn-Y6g.png" /></p>

<p>合併発送する商品の内容を確認し、問題なければ「発送する荷物を確定する」をクリックしてください。</p>

<p><img src="/assets/bea62c251f1b/1*PVcM448g7pTwBjOeKh3n0Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="561" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjU2MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*PVcM448g7pTwBjOeKh3n0Q.png" /></p>

<p>「その他の有料ラッピングサービスを選択」をクリックしてください。</p>

<p><img src="/assets/bea62c251f1b/1*5tmccDXzlPpxIvo1CMNIow.webp" alt="" loading="lazy" decoding="async" width="1400" height="603" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjYwMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*5tmccDXzlPpxIvo1CMNIow.png" /></p>

<p>包装サービスを選択できます：(i をクリックすると画像付きの説明があります)</p>

<ul>
  <li>
    <p>梱包箱、靴箱、広告チラシ、カタログ、納品書などを取り除く：重量と体積を減らし、送料を節約します。</p>
  </li>
  <li>
    <p>荷物の防水処理</p>
  </li>
  <li>
    <p>国際配送専用の強化箱を使用：私が確認しましたが、実際には大きな段ボール箱と緩衝材で商品を包んでいるだけです。</p>
  </li>
</ul>

<h4 id="梱包依頼発送先の選択">梱包依頼（発送先の選択）</h4>

<p><img src="/assets/bea62c251f1b/1*uJDDeUEF1kAT3thtzpzwDw.webp" alt="" loading="lazy" decoding="async" width="1400" height="333" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjMzMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*uJDDeUEF1kAT3thtzpzwDw.png" /></p>

<p><img src="/assets/bea62c251f1b/1*yrnzSlMcUafXAIhIaJy4Hw.webp" alt="" loading="lazy" decoding="async" width="743" height="797" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NDMiIGhlaWdodD0iNzk3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*yrnzSlMcUafXAIhIaJy4Hw.png" /></p>

<p>発送先住所を入力してください：</p>

<ul>
  <li>パスポートの英語氏名、<a href="https://www.post.gov.tw/post/internet/SearchZone/index.jsp?ID=130112" target="_blank">英語の住所</a>、<strong>あなたの携帯電話番号（先頭の0を外して886に変更）</strong></li>
</ul>

<p><img src="/assets/bea62c251f1b/1*3o3wRZOd4t8lldmdU-NObw.webp" alt="" loading="lazy" decoding="async" width="1200" height="676" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*3o3wRZOd4t8lldmdU-NObw.png" /></p>

<p>送信後のステータスは「梱包作業中」になり、作業完了後に支払いと発送が行われます。</p>

<p><img src="/assets/bea62c251f1b/1*5ogwtSaFBNCO3r2gJIA48w.webp" alt="" loading="lazy" decoding="async" width="1200" height="537" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjUzNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*5ogwtSaFBNCO3r2gJIA48w.png" /></p>

<p>だいたい翌朝には梱包完了の通知が届きました。</p>

<h4 id="転送送料の支払い発送依頼">転送送料の支払い、発送依頼</h4>

<p><img src="/assets/bea62c251f1b/1*lA5p3upIWTdp6FTDrOdtqA.webp" alt="" loading="lazy" decoding="async" width="1160" height="725" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTYwIiBoZWlnaHQ9IjcyNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*lA5p3upIWTdp6FTDrOdtqA.png" /></p>

<p>状態：支払い待ち。</p>

<p><img src="/assets/bea62c251f1b/1*psFozqxO72KXbbEKY0k37g.webp" alt="" loading="lazy" decoding="async" width="1098" height="887" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDk4IiBoZWlnaHQ9Ijg4NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*psFozqxO72KXbbEKY0k37g.png" /></p>

<p>「荷物一覧」→「未払い」荷物→「支払いへ進む」。</p>

<p><img src="/assets/bea62c251f1b/1*XC-tScyTBFqb-XGTedttWA.webp" alt="" loading="lazy" decoding="async" width="1200" height="530" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjUzMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*XC-tScyTBFqb-XGTedttWA.png" /></p>

<blockquote>
  <p><strong><em>最終サイズ、重量：2,330 g、38 x 30 x 21 cm</em></strong></p>
</blockquote>

<p>荷物の内容と受取人情報を確認し、問題なければ「配送方法を選択」をクリックしてください。</p>

<p><img src="/assets/bea62c251f1b/1*q9ImvJKflcvx1uHFSxS4pw.webp" alt="" loading="lazy" decoding="async" width="1200" height="577" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU3NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*q9ImvJKflcvx1uHFSxS4pw.png" /></p>

<p>選択できます：</p>

<ul>
  <li>
    <p>DHL 快速便（スーパースピード航空便）：1〜3日 9,100円<br />
友人の意見によると、DHLを利用する場合は必ず<a href="https://roo.cash/blog/dhl-introduction/#DHL_%E5%85%88%E7%A8%85%E5%BE%8C%E6%94%BE%E6%98%AF%E4%BB%80%E9%BA%BC%EF%BC%9F" target="_blank">先税後放</a>を申請して、税関での検査後に追加の処理費用がかからないようにすることをおすすめします。</p>
  </li>
  <li>
    <p><strong>EMS 特急航空便：3〜8日 6,550円（私はこれを選び、実際には2日で届き、とても早かったです）</strong></p>
  </li>
  <li>
    <p>ECMS 経済航空便：6〜11日 6,280円</p>
  </li>
  <li>
    <p>船便：20〜40日、5,620円</p>
  </li>
</ul>

<blockquote>
  <p><em>価格は<a href="https://globalexpress.rakuten.co.jp/estimate/" target="_blank">費用見積もりツール</a>で表示された金額とほぼ同じです。</em></p>
</blockquote>

<p>次に、クレジットカードまたはPaypalで支払いを完了してください：</p>

<p><img src="/assets/bea62c251f1b/1*uPqI-nncfu_uToP6427_Jw.webp" alt="" loading="lazy" decoding="async" width="1200" height="561" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU2MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*uPqI-nncfu_uToP6427_Jw.png" /></p>

<p><img src="/assets/bea62c251f1b/1*ydX1HyUTXvumBk__QH4UJw.webp" alt="" loading="lazy" decoding="async" width="1200" height="569" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU2OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*ydX1HyUTXvumBk__QH4UJw.png" /></p>

<p>送料でも楽天ポイントが貯まる（1%）！</p>

<h4 id="出荷委託完了">出荷委託完了</h4>

<p><img src="/assets/bea62c251f1b/1*2jZefbTEBHYcnc8szKlx6Q.webp" alt="" loading="lazy" decoding="async" width="1208" height="492" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjA4IiBoZWlnaHQ9IjQ5MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*2jZefbTEBHYcnc8szKlx6Q.png" /></p>

<p><img src="/assets/bea62c251f1b/1*_f1zLXqHYGcWXdgzxCfL_g.webp" alt="" loading="lazy" decoding="async" width="1161" height="777" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTYxIiBoZWlnaHQ9Ijc3NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*_f1zLXqHYGcWXdgzxCfL_g.png" /></p>

<p>状態は「出荷作業中」になります。</p>

<h4 id="ezwayの登録完了">EZWayの登録完了</h4>

<p>海外から商品を購入した経験がない場合は、<a href="https://www.rakuten.com.tw/magazine/life/2022/012802/#D" target="_blank">必ずEZWay実名認証を完了し、EZWayアプリをダウンロードして登録および実名認証を行ってください</a> 。</p>

<h4 id="楽天転送の発送">楽天転送の発送</h4>

<p><img src="/assets/bea62c251f1b/1*ZNzn3Zpuk_HN0kbmo_zEzg.webp" alt="" loading="lazy" decoding="async" width="849" height="698" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NDkiIGhlaWdodD0iNjk4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/bea62c251f1b/1*ZNzn3Zpuk_HN0kbmo_zEzg.png" /></p>

<p>楽天が出荷を完了すると通知が届き、追跡番号で荷物の状況を確認できます。</p>

<blockquote>
  <p><em>発送開始直後は見つからないことがありますが、しばらく経ってから再度確認すると表示されます。</em></p>
</blockquote>

<p><img src="/assets/bea62c251f1b/1*U0L23fpYbBKTeoPtZcLsBA.webp" alt="" loading="lazy" decoding="async" width="904" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*U0L23fpYbBKTeoPtZcLsBA.png" /></p>

<h4 id="商品の到着を待つ">商品の到着を待つ！</h4>

<p>ここまでで、日本の楽天サイトでの登録、楽天転送の利用、注文、発送、台湾への配送、EZWayの手続きがすべて完了しました。あとは商品が届くのを待つだけです！</p>

<h3 id="楽天転送horie-チタンカップ-開封レビュー">楽天転送、<a href="https://a.r10.to/hkPx9m" target="_blank">Horie チタンカップ</a> 開封レビュー</h3>

<p>10/14に楽天転送で発送依頼をし、10/16にはもう受け取りました！</p>

<p><img src="/assets/bea62c251f1b/1*LnzDj0-qp5JrhXe40RiewQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1088" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwODgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/bea62c251f1b/1*LnzDj0-qp5JrhXe40RiewQ.png" /></p>

<p>二つのカップと一冊の雑誌の実際の箱はそれほど大きくありません。</p>

<p><img src="/assets/bea62c251f1b/1*x7NZZf3oWLDLAqZzktyYoA.webp" alt="" loading="lazy" decoding="async" width="1200" height="1052" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwNTIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/bea62c251f1b/1*x7NZZf3oWLDLAqZzktyYoA.png" /></p>

<p>日本製の注意シールを貼る。</p>

<p><img src="/assets/bea62c251f1b/1*Rub-oAEfRnZjpn4eIAhPHg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1157" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjExNTciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/bea62c251f1b/1*Rub-oAEfRnZjpn4eIAhPHg.png" /></p>

<p>国際配送専用の強化箱とは、この段ボール箱に加えて、周囲と底部に衝撃吸収用の紙包装を施したものです。</p>

<p><img src="/assets/bea62c251f1b/1*sR3X_vfh6_7VH8x7jTA4GQ.webp" alt="" loading="lazy" decoding="async" width="913" height="1102" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTMiIGhlaWdodD0iMTEwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*sR3X_vfh6_7VH8x7jTA4GQ.png" /></p>

<p><img src="/assets/bea62c251f1b/1*a2ZQxQbXhyFm790bAqnZ4Q.webp" alt="" loading="lazy" decoding="async" width="931" height="1184" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzEiIGhlaWdodD0iMTE4NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*a2ZQxQbXhyFm790bAqnZ4Q.png" /></p>

<p>上はAmazonで買った雑誌です（郵送の紙包装は破れていましたが、中身は無事です）、下はHorieのチタンカップです。</p>

<p><img src="/assets/bea62c251f1b/1*jDdIWaMN0U_l0KrULJjk7g.webp" alt="" loading="lazy" decoding="async" width="1200" height="925" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkyNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*jDdIWaMN0U_l0KrULJjk7g.png" /></p>

<p>Horieのチタンカップの箱は、そのままの状態で楽天転送の箱に入れられます。</p>

<blockquote>
  <p><em>転送時の梱包で元の包装を取り除いて体積と重量を減らすオプションを選ぶと、送料を節約できます。</em></p>
</blockquote>

<p><img src="/assets/bea62c251f1b/1*ZVCaomYElKOQktBAGerrkg.webp" alt="" loading="lazy" decoding="async" width="1200" height="817" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgxNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*ZVCaomYElKOQktBAGerrkg.png" /></p>

<p>内容物：2個のチタンカップ。</p>

<h3 id="horie-チタンカップ-1"><a href="https://a.r10.to/hkPx9m" target="_blank">Horie チタンカップ</a></h3>

<p><img src="/assets/bea62c251f1b/1*bXj9-XVgjfsVta6cZg8Fpw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*bXj9-XVgjfsVta6cZg8Fpw.jpeg" /></p>

<p><img src="/assets/bea62c251f1b/1*z2CIeS7Y4Z65SV2WXSv-1Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/bea62c251f1b/1*z2CIeS7Y4Z65SV2WXSv-1Q.jpeg" /></p>

<p><img src="/assets/bea62c251f1b/1*EZAkrzE5WkIEF0YMSoT3CA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/bea62c251f1b/1*EZAkrzE5WkIEF0YMSoT3CA.jpeg" /></p>

<p>全体の色彩と模様、グラデーションが非常に鮮やかで幻想的で、美しさが現実離れしています。</p>

<p><img src="/assets/bea62c251f1b/1*F_L3JKPr1kd-Ljs9c2TA2Q.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/bea62c251f1b/1*F_L3JKPr1kd-Ljs9c2TA2Q.jpeg" /></p>

<p>すぐに生ビールを一瓶開けて氷を入れてテストしましたが、保冷効果は確かに良く、ビールもクリーミーな泡が立ってとても美味しく、<strong>しかも本当に結露しません</strong>。</p>

<h3 id="最終費用計算">最終費用計算</h3>

<ul>
  <li>
    <p><a href="https://a.r10.to/hkPx9m" target="_blank">Horie チタンカップ</a> 窯作り ブースター/400ml ¥19,800 円 — NT$4,079</p>
  </li>
  <li>
    <p>送料負担/人：NT$665</p>
  </li>
  <li>
    <p>関税：かかっていません</p>
  </li>
</ul>

<p>合計：NT$4,744で入手。</p>

<blockquote>
  <p><strong><em>チタンカップは非常に軽いため、数人でまとめて購入し送料を分担すれば、価格を約NT4,200まで抑えられると思います。私は2個だけ購入したので、送料が少し高くなりました。</em></strong></p>
</blockquote>

<blockquote>
  <p>もちろん一番お得なのは、直接日本の百貨店で購入して免税を受けることです！価格は約NT$3,600と予想されます。</p>
</blockquote>

<p><em><a href="https://medium.com/zrealm-life/%E6%97%A5%E6%9C%AC%E6%B5%B7%E5%A4%96%E8%B3%BC%E7%89%A9%E5%AF%84%E9%80%81%E5%8F%B0%E7%81%A3%E6%95%99%E5%AD%B8-%E4%BD%BF%E7%94%A8%E6%A8%82%E5%A4%A9%E9%9B%86%E9%81%8B%E8%B3%BC%E8%B2%B7%E6%A8%82%E5%A4%A9%E6%8B%8D%E8%B3%A3%E8%88%87-amazon-%E5%95%86%E5%93%81-horie-%E9%88%A6%E6%9D%AF-bea62c251f1b" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>によって変換されました。</em></p>]]></content>
  </entry><entry>
    <title type="html">東京近郊自由行｜川越小江戸＆熱海海上花火大会5日間完全ガイド</title>
    <link href="https://jp.zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E6%9D%B1%E4%BA%AC%E8%BF%91%E9%83%8A%E8%87%AA%E7%94%B1%E8%A1%8C-%E5%B7%9D%E8%B6%8A%E5%B0%8F%E6%B1%9F%E6%88%B8-%E7%86%B1%E6%B5%B7%E6%B5%B7%E4%B8%8A%E8%8A%B1%E7%81%AB%E5%A4%A7%E4%BC%9A5%E6%97%A5%E9%96%93%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-958599363857/" rel="alternate" type="text/html" title="東京近郊自由行｜川越小江戸＆熱海海上花火大会5日間完全ガイド" />
    <published>2025-10-10T19:01:28+08:00</published>
    <updated>2025-10-16T23:55:33+08:00</updated>
    <id>https://jp.zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/958599363857</id><summary type="html">東京市内と近郊の川越小江戸や熱海花火大会を5日間で満喫する交通手段と体験方法を詳しく解説。効率的な旅程で充実の自由旅行を実現します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="Z 度旅行遊記" /><category term="生活" /><category term="旅行" /><category term="日本" /><category term="東京" /><category term="旅行記" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/958599363857/1*E-ZA-OYCi5vsTBGlsxyS0g.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E6%9D%B1%E4%BA%AC%E8%BF%91%E9%83%8A%E8%87%AA%E7%94%B1%E8%A1%8C-%E5%B7%9D%E8%B6%8A%E5%B0%8F%E6%B1%9F%E6%88%B8-%E7%86%B1%E6%B5%B7%E6%B5%B7%E4%B8%8A%E8%8A%B1%E7%81%AB%E5%A4%A7%E4%BC%9A5%E6%97%A5%E9%96%93%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-958599363857/"><![CDATA[<h3 id="旅行記-2025年-東京エリア--川越小江戸と熱海海上花火大会-5日間自由旅行">[旅行記] 2025年 東京エリア — 川越小江戸と熱海海上花火大会 5日間自由旅行</h3>

<p>東京市内＋近郊 5日4泊自由旅行、熱海花火大会と川越日帰り交通・体験完全ガイド</p>

<p><img src="/assets/958599363857/1*E-ZA-OYCi5vsTBGlsxyS0g.webp" alt="夏の熱海花火" loading="lazy" decoding="async" width="1400" height="933" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjkzMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*E-ZA-OYCi5vsTBGlsxyS0g.jpeg" /></p>

<p>夏の熱海花火大会</p>

<p>新しい仕事が始まったばかりなので、まずは充電して、<a href="/posts/z-度旅行記/東京自由行-5日間の観光-グルメ-宿泊情報を徹底解説-9da2c51fa4f2/">再訪東京</a> — 一生に一度は見るべき日本の花火大会と東京近郊の川越日帰り旅行へ。</p>

<h4 id="前回の旅程">前回の旅程</h4>

<blockquote>
  <p><em>前回の「<a href="/posts/z-度旅行記/東京自由行-5日間の観光-グルメ-宿泊情報を徹底解説-9da2c51fa4f2/"><strong>[旅行記] 2023 東京 5日間自由行</strong></a>」は2023年6月に東京に行きましたが、9月ほど暑くはありませんでした。前回は主に、東京タワー、Shibuya Sky、スカイツリー、浅草雷門、ディズニーシー、横浜ガンダム、横浜ロープウェイ、お台場、新宿、皇居に行きました。</em></p>
</blockquote>

<blockquote>
  <p><em>興味のある方は <a href="/posts/z-度旅行記/東京自由行-5日間の観光-グルメ-宿泊情報を徹底解説-9da2c51fa4f2/">こちらからご覧ください</a> 。</em></p>
</blockquote>

<h3 id="楽しみ">楽しみ</h3>

<ul>
  <li>
    <p>Day 1 (09/13 土) — 東京到着、渋谷、Shibuya Sky</p>
  </li>
  <li>
    <p>Day 2 (09/14 日) — 川越日帰り旅行、夜は池袋でショッピング</p>
  </li>
  <li>
    <p>Day 3 (09/15 月) — 東京駅地下街、熱海花火大会</p>
  </li>
  <li>
    <p>Day 4 (09/16 火) — 麻布台 teamLab、原宿ショッピング、原宿 HARRY カワウソカフェ</p>
  </li>
  <li>
    <p>Day 5 (09/17 水) — 上野散策、帰路</p>
  </li>
</ul>

<h4 id="渋谷スカイ">渋谷スカイ</h4>

<ul>
  <li>
    <p><strong>Shibuya Skyのチケットは非常に人気があるため、必ず事前に購入してください。</strong></p>
  </li>
  <li>
    <p><a href="https://www.shibuya-scramble-square.com.t.apy.hp.transer.com/sky/ticket/" target="_blank">公式サイト</a> 販売開始時間：台湾時間の夜11時から、+2週間後の入場日のチケットを購入可能<br />
公式サイトで購入する際は、まず会員登録と購入手順の確認をおすすめします。チケットの利用者名はニックネームでも構いませんので、パスポートの正式な名前を入力する必要はありません。</p>
  </li>
  <li>
    <p>私たちは18:40～18:59の夜景の時間帯を購入しましたが、もっと早く夕日を見るか、夕食後の最終回21:00を選ぶこともできます。</p>
  </li>
  <li>
    <p>その他の購入方法： <a href="https://www.kkday.com/zh-tw/product/133300-shibuya-sky-observatory-e-ticket-tokyo?cid=19365" target="_blank">KKday 渋谷SHIBUYA SKY展望台チケット｜即購入・即利用</a></p>
  </li>
</ul>

<blockquote>
  <p><em>価格：¥3,400 円/人</em></p>
</blockquote>

<h4 id="熱海花火大会">[熱海花火大会</h4>

<p>熱海花火大会](https://hoshinoresorts.com/zh_tw/hotels/risonareatami/activities/13288/){:target=”_blank”} 公式サイト。</p>

<ul>
  <li>
    <p>2025年 打ち上げ日：3/23、4/20、4/28、5/31、7/25、8/5、8/8、8/18、8/25、 <strong>9/15</strong> 、9/23、10/13、11/3、11/24、12/7、12/19。</p>
  </li>
  <li>
    <p>7月、8月の打ち上げ時間：午後8時15分〜午後8時40分（25分間）</p>
  </li>
  <li>
    <p><strong>その他の月の打ち上げ時間：午後8時20分～午後8時40分（20分間）</strong></p>
  </li>
</ul>

<p>ビーチでの花火解放、入場無料、指定席なしで、JR熱海駅から徒歩で行けます。<strong>念のため、往復のJRチケットか熱海の宿泊予約だけ事前にしておけば十分です</strong>。</p>

<p><strong>ピクニックマットの持参を強くおすすめします！ピクニックマットの持参を強くおすすめします！ピクニックマットの持参を強くおすすめします！</strong></p>

<blockquote>
  <p><em>私たちは9月15日午後8時20分の打ち上げ花火大会に行きました。</em></p>
</blockquote>

<h4 id="麻布台-teamlab-teamlab-borderless-森ビル-デジタルアートミュージアム"><a href="https://borderless-azabudai.ticket.teamlab.art/#/" target="_blank">麻布台 TeamLab (teamLab Borderless: 森ビル デジタルアートミュージアム)</a></h4>

<ul>
  <li>
    <p>チケットはかなり多いですが、やはり出発前に事前購入をおすすめします。</p>
  </li>
  <li>
    <p>その他の購入チャネル： <a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Factivity%2F20707-teamlab-borderless-admission-ticket-tokyo%2F" target="_blank">東京teamLab Borderlessデジタルアートミュージアムチケット</a></p>
  </li>
</ul>

<blockquote>
  <p><em>価格：¥4,800 円/人</em></p>
</blockquote>

<h4 id="ｈａｒｒｙ原宿テラス店-カワウソカフェ"><a href="https://harinezumi-cafe.com/store/harajuku-terrace/" target="_blank">ＨＡＲＲＹ原宿テラス店</a> カワウソカフェ</h4>

<p>以前IGで話題になったカワウソと触れ合える<a href="https://harinezumi-cafe.com/store/harajuku-terrace/" target="_blank">カフェ</a>。</p>

<p><img src="/assets/958599363857/1*gV6F9gn_uu9pYeVZSlPQbQ.webp" alt="&lt;https://www.instagram.com/p/DPBKurVD99c/&gt;" loading="lazy" decoding="async" width="1148" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQ4IiBoZWlnaHQ9IjEyMDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*gV6F9gn_uu9pYeVZSlPQbQ.png" /></p>

<p><a href="https://www.instagram.com/p/DPBKurVD99c/" target="_blank">https://www.instagram.com/p/DPBKurVD99c/</a></p>

<ul>
  <li>
    <p><a href="https://book.squareup.com/appointments/3kuc83ozz99u5q/location/G3XVJ4FPKRGCP/services/5TOZDR3PNU7X52TOXELQN575" target="_blank">公式予約</a></p>
  </li>
  <li>
    <p>東京の他店舗も利用可能です <a href="https://harinezumi-cafe.com/store/" target="_blank">公式サイトで確認</a> 。</p>
  </li>
  <li>
    <p><strong>事前予約をおすすめします。当日は満席の可能性があります。</strong></p>
  </li>
  <li>
    <p>日程変更があってもキャンセルは無料です。</p>
  </li>
  <li>
    <p>時間：16:30–17:30</p>
  </li>
</ul>

<blockquote>
  <p><em>価格：¥3,080/人 1時間基本料金 + 現地で追加 ¥880/人 でカワウソと5分間のふれあい。</em></p>
</blockquote>

<p><a href="https://kantenlife.tw/2024/04/18/house-of-otters-japan/#%E6%97%A5%E6%9C%AC%E6%B0%B4%E7%8D%BA%E5%92%96%E5%95%A1%E5%BB%B3%EF%BD%9C%E3%82%AB%E3%83%AF%E3%82%A6%E3%82%BD_%E8%8B%A5%E6%9E%97%E3%81%AE%E5%AE%B6%E3%80%81HARRY_HARAJUKU_terrace%E6%AF%94%E8%BC%83%E5%88%86%E4%BA%AB" target="_blank"><strong>しかし後で調べたところ、もう一軒のカワウソ_若林の家の方が良さそうで、交流時間が長いです。</strong></a></p>

<h3 id="行">行</h3>

<h4 id="航空券--日本航空-japan-airlines">航空券 — 日本航空 Japan Airlines</h4>

<ul>
  <li>
    <p>往路 9月13日：JL802 日本航空 — 10:00 TPE 桃園国際空港 T2 -&gt; 14:25 NRT 成田空港 T2</p>
  </li>
  <li>
    <p>帰路 9月17日：JL809 日本航空 — 18:10 NRT 成田空港第2ターミナル -&gt; 18:10 TPE 桃園国際空港第2ターミナル</p>
  </li>
</ul>

<blockquote>
  <p><em>価格：NT $12,324/人</em></p>
</blockquote>

<p><a href="https://www.jal.co.jp/tw/zhtw/inter/baggage/checked/" target="_blank">また、日本航空の受託手荷物許容量はかなり多く、エコノミークラスでは：<strong>2個まで、1個あたり23kgまで</strong></a></p>

<h4 id="jr-新幹線-東京---熱海--45分">JR 新幹線 東京 &lt;-&gt; 熱海 (~= 45分)</h4>

<p>当日の往復の電車が混雑するのを心配して、事前に切符を購入しました。</p>

<ul>
  <li>
    <p>販売開始時間：台湾時間の夜11時から、+4週間後の日付のチケットを購入可能</p>
  </li>
  <li>
    <p><a href="https://e5489.jr-odekake.net/e5489/ibpc/CBTrainEntryExternalPC?LANG=tc" target="_blank">公式サイトで購入</a> または <a href="https://www.kkday.com/zh-tw/transportation/japan-rail?cid=19365" target="_blank">KKday</a> / <a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Fjapan-rail%2F" target="_blank">Klook</a> で購入可能（価格はご自身で比較してください）</p>
  </li>
</ul>

<blockquote>
  <p><em>私たちが購入したのは：</em></p>
</blockquote>

<blockquote>
  <p><em>- <strong>東京 14:57 -&gt; 熱海 15:42</strong> — こだま Kodama 735</em></p>
</blockquote>

<blockquote>
  <p><em>- <strong>熱海 22:02 -&gt; 東京 22:48 —</strong> こだま Kodama 752</em></p>
</blockquote>

<blockquote>
  <p><em>価格：NT $1,882+NT $56（予約代行プラットフォームの座席指定料金）/人</em></p>
</blockquote>

<h4 id="skyliner-京成電鉄チケット--41分"><a href="https://www.kkday.com/zh-tw/product/7913-keisei-skyliner-narita-airport-express-ticket?cid=19365" target="_blank">Skyliner 京成電鉄チケット</a> (~= 41分)</h4>

<p>現在、成田空港から東京市内（上野）への最速の方法だと思います。</p>

<ul>
  <li>
    <p>自由席なし</p>
  </li>
  <li>
    <p>KKdayで購入： <a href="https://www.kkday.com/zh-tw/product/7913-keisei-skyliner-narita-airport-express-ticket?cid=19365" target="_blank">Skyliner 京成電鉄チケット</a></p>
  </li>
  <li>
    <p>ネットで事前に購入すると安く、駅で座席指定ができるため便利に利用できます。</p>
  </li>
</ul>

<blockquote>
  <p><em>価格：NT $912（往復2枚のチケット）/人</em></p>
</blockquote>

<blockquote>
  <p><em>注意すべき点は、KKdayで往復チケットを購入すると、往復分の2枚のチケットが発行されるため、購入ミスではないということです。</em></p>
</blockquote>

<h4 id="川越周遊券電車バス--30-分"><a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Factivity%2F100464-kawagoe-pass-digital-ticket%2F" target="_blank">川越周遊券（電車＋バス）</a> (~= 30 分)</h4>

<ul>
  <li>
    <p>東武東上線往復：池袋駅 -&gt; 川越駅または川越市駅</p>
  </li>
  <li>
    <p>東武バス全日乗り放題（東武小江戸循環バスを含む）</p>
  </li>
  <li>
    <p>ご注意：バスには西武と東武がありますが、このチケットは東武のものです。</p>
  </li>
  <li>
    <p>KLook 購入： <a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Factivity%2F100464-kawagoe-pass-digital-ticket%2F" target="_blank">川越割引周遊券 Kawagoe Discount Pass</a></p>
  </li>
  <li>
    <p>交換は不要で、利用前にオンラインで引き換えを行い、QRコードを提示して電車やバスの運転手に見せるだけです。</p>
  </li>
</ul>

<blockquote>
  <p><em>価格：NT $214/人</em></p>
</blockquote>

<h4 id="空港送迎">空港送迎</h4>

<ul>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/airport-transfer?cid=19365" target="_blank">KKday 空港送迎予約</a> / <a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Fairport-transfers%2F" target="_blank">Klook 空港送迎予約</a></p>
  </li>
  <li>
    <p>現在、両方のKは空港送迎サービスを提供しており、安くて安全、かつ速いです。価格を比較して自分に合ったものを選べます。</p>
  </li>
</ul>

<blockquote>
  <p><em>双北 -&gt; 桃機</em></p>
</blockquote>

<blockquote>
  <p><em>価格：NT$752/台</em></p>
</blockquote>

<h4 id="esim">eSIM</h4>

<p>同様にKKdayで5G使い放題のeSIMを直接購入しましたが、今回は東京、熱海、川越で特に問題や速度制限に遭うことはありませんでした。</p>

<ul>
  <li>KKday 購入： <a href="https://www.kkday.com/zh-tw/product/121004-unlimited-data-esim-card-japan?cid=19365" target="_blank">日本 eSIM 無制限データ KDDI / Softbank</a></li>
</ul>

<blockquote>
  <p><em>価格：NT $309／5日間／無制限データ通信</em></p>
</blockquote>

<h4 id="日本を訪れる">日本を訪れる</h4>

<p><a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E4%BA%AC%E9%98%AA%E7%A5%9E%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-%E4%BA%AC%E9%83%BD%E5%A4%A7%E9%98%AA%E7%A5%9E%E6%88%B68%E6%97%A5%E9%81%8A%E5%85%A8%E7%B4%80%E9%8C%84%E8%88%87%E5%AF%A6%E7%94%A8%E4%BA%A4%E9%80%9A%E4%BD%8F%E5%AE%BF%E6%8C%87%E5%8D%97-76d66c2e34af/#20241125-%E6%9B%B4%E6%96%B0%E5%85%A5%E5%A2%83%E5%AF%A9%E6%9F%A5%E8%88%87%E6%B5%B7%E9%97%9C%E7%94%B3%E5%A0%B1qr-code-%E5%B7%B2%E5%90%88%E4%BD%B5%E6%88%90%E5%90%8C%E4%B8%80%E5%80%8B%E5%85%A5%E5%A2%83%E5%AE%A1%E6%9F%A5%E5%8F%8A%E6%B5%B7%E5%85%B3%E7%94%B3%E6%8A%A5%E7%9A%84qr%E7%A0%81%E6%B2%92%E6%9C%89%E8%97%8D%E7%A2%BC%E9%BB%83%E7%A2%BC%E5%8D%80%E5%88%A5%E4%BB%A5%E4%B8%8B%E5%85%A7%E5%AE%B9%E5%8F%AA%E7%95%B6%E7%B4%80%E9%8C%84%E5%8F%AF%E4%BB%A5%E5%BF%BD%E7%95%A5" target="_blank">事前に登録を済ませておけば大丈夫です。現在、入国審査と税関審査のQRコードは一つに統合されています。</a></p>

<h3 id="宿泊">宿泊</h3>

<p>出発日が近かったため、価格と利便性を総合的に比較して、新橋駅周辺に宿泊することにしました。（前回は汐留に泊まりましたが、新橋の方が便利だと感じました）</p>

<h4 id="東京新橋大和-roynet-ホテル-4泊"><a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Fhotels%2Fdetail%2F127656-daiwa-roynet-hotel-shimbashi%2F" target="_blank">東京新橋大和 ROYNET ホテル</a> (4泊)</h4>

<p><img src="/assets/958599363857/1*FPa2l4mYfm_ApuJt_LqSag.webp" alt="東京新橋大和 ROYNET ホテル" loading="lazy" decoding="async" width="579" height="539" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NzkiIGhlaWdodD0iNTM5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/958599363857/1*FPa2l4mYfm_ApuJt_LqSag.png" /></p>

<p><a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Fhotels%2Fdetail%2F127656-daiwa-roynet-hotel-shimbashi%2F" target="_blank">東京新橋大和 ROYNET ホテル</a></p>

<ul>
  <li>
    <p><a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Fhotels%2Fdetail%2F127656-daiwa-roynet-hotel-shimbashi%2F" target="_blank">同じくKlookから直接予約して、ポイントを貯める</a></p>
  </li>
  <li>
    <p>新橋駅から徒歩約2分で、とても近いです。</p>
  </li>
  <li>
    <p>5泊5日間、ホテルを変えずに滞在します。</p>
  </li>
</ul>

<blockquote>
  <p><em>価格：NT$ 18,404／4泊／2名／スタンダードダブルルーム、約 NT$ 2,300／1人1泊あたり。</em></p>
</blockquote>

<blockquote>
  <p>準備完了！出発！</p>
</blockquote>

<p><a href="https://digital.jal.co.jp/ssci/identification?lang=zh-tw" target="_blank"><strong>出発の24時間前からオンラインチェックインと座席指定が可能で、空港では直接荷物を預けられ、手続きがスムーズになります。</strong></a></p>

<h3 id="day-1-0913-土--東京到着shibuya-sky">Day 1 (09/13 土) — 東京到着、Shibuya Sky</h3>

<h4 id="0650-空港送迎に乗車">06:50 空港送迎に乗車</h4>

<h4 id="0720-桃園空港第2ターミナル到着">07:20 桃園空港第2ターミナル到着</h4>

<p><img src="/assets/958599363857/1*TkF8qP3e1-iladiHOZgERQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*TkF8qP3e1-iladiHOZgERQ.jpeg" /></p>

<h4 id="0730-荷物のパッキングと預け入れ">07:30 荷物のパッキングと預け入れ</h4>

<p><img src="/assets/958599363857/1*sNzgznqv8RxRYfwyCaIntg.webp" alt="" loading="lazy" decoding="async" width="1200" height="843" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*sNzgznqv8RxRYfwyCaIntg.png" /></p>

<p>1番の端のカウンターに割り当てられ、<a href="https://digital.jal.co.jp/ssci/identification?lang=zh-tw" target="_blank">事前にオンラインチェックインを完了</a>していたため、そのまま荷物の預け入れに並びましたが、前の人が時間がかかっていて、荷物の預け入れ手続きが終わるまで約30分以上待ちました。</p>

<h4 id="-0820-セキュリティチェックと出国手続き完了">~= 08:20 セキュリティチェックと出国手続き完了</h4>

<p><img src="/assets/958599363857/1*lKRxUWP4BGQA1q97X3jJJg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*lKRxUWP4BGQA1q97X3jJJg.jpeg" /></p>

<p>朝早は結構混んでいて、だいたい8:20頃に保安検査を終えて出国しました。まず2階でモスバーガーを朝食に食べました。割り当てられた搭乗口は一番遠いD1でした。</p>

<h4 id="第二ターミナル出国免税店-le-labo">第二ターミナル出国免税店 Le Labo</h4>

<p><img src="/assets/958599363857/1*wyJNusrf7ElLdfZ33YaPWA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*wyJNusrf7ElLdfZ33YaPWA.jpeg" /></p>

<p>意外に第二ターミナルの出国免税店でLe Laboを発見しました。店員さんによると現在キャンペーン中で、新規会員登録でクーポンを使うと50mlがNT$5,500になり、日本国内の約NT$5,800より安いです。</p>

<p><strong>2025年最新収集の価格表 — 50ml：</strong></p>

<ul>
  <li>
    <p>台湾店舗価格：NT $7,600</p>
  </li>
  <li>
    <p>台湾空港店舗免税価格：NT $5,500（キャンペーン価格）</p>
  </li>
  <li>
    <p>日本店舗の免税後価格：約NT $5,700</p>
  </li>
  <li>
    <p><a href="https://www.fasola.jp/en/searchByBrand.aspx" target="_blank"><strong>日本の空港店舗</strong></a> <strong>免税価格：約 NT $5,200 🤩 — 今回は成田空港</strong> T2 <strong>ターミナルの出国後に購入しました。</strong></p>
  </li>
</ul>

<p><img src="/assets/958599363857/1*4AU39FGOzbR7TnCVzCCjKg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*4AU39FGOzbR7TnCVzCCjKg.jpeg" /></p>

<p><img src="/assets/958599363857/1*sgPd1BrkZsr2F37f1m1Dlg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*sgPd1BrkZsr2F37f1m1Dlg.jpeg" /></p>

<p><img src="/assets/958599363857/1*I6HuL5NdPzQxp3lu43fiUw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*I6HuL5NdPzQxp3lu43fiUw.jpeg" /></p>

<p><img src="/assets/958599363857/1*gkCuhDtktYmN6ed170fRZg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*gkCuhDtktYmN6ed170fRZg.jpeg" /></p>

<p>空港で搭乗までの待ち時間に、D1のThe North Faceの隣に無料のマッサージチェアが2列あります（近くの店舗で無料トークンをもらって利用可能）。</p>

<h4 id="0940-搭乗口へ向かい搭乗準備">09:40 搭乗口へ向かい搭乗準備</h4>

<p><img src="/assets/958599363857/1*U5QpF19SbJlVAllxZZiQMA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*U5QpF19SbJlVAllxZZiQMA.jpeg" /></p>

<p><img src="/assets/958599363857/1*izSSFMEAPqbhFtTgt13ndw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*izSSFMEAPqbhFtTgt13ndw.jpeg" /></p>

<p>今回乗った飛行機はBOEING 737–800で、機体は少し古めでした。</p>

<blockquote>
  <p><em>しかし、帰宅後に気づきましたが、機内で無料の1時間WiFiが利用できました。</em></p>
</blockquote>

<h4 id="1006-離陸">10:06 離陸</h4>

<p><img src="/assets/958599363857/1*McNWkLo576Z3uJTm9QgYWA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*McNWkLo576Z3uJTm9QgYWA.jpeg" /></p>

<h4 id="japan-airlines-機内食">JAPAN AIRLINES 機内食</h4>

<p><img src="/assets/958599363857/1*VoM9bEiz7mMma7fAwp48tw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*VoM9bEiz7mMma7fAwp48tw.jpeg" /></p>

<p><img src="/assets/958599363857/1*tu0L7uohZIqsd9V4JlKGFg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*tu0L7uohZIqsd9V4JlKGFg.jpeg" /></p>

<p><img src="/assets/958599363857/1*s69aVqVz7J7wXFSNi66SsQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*s69aVqVz7J7wXFSNi66SsQ.jpeg" /></p>

<p>飛行機は少し古いですが、機内食は本当に美味しかったです。ハンバーグのミートソースパスタ、小さな蕎麦と豆腐の冷やし麺、そしてデザートのレモンプリン（美味しい！）がありました。</p>

<h4 id="1439-日本成田国際空港に到着14分遅延">14:39 日本成田国際空港に到着（14分遅延）</h4>

<p><img src="/assets/958599363857/1*0Dvy2jcY6ED8uW6NgmxcXw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*0Dvy2jcY6ED8uW6NgmxcXw.jpeg" /></p>

<p><img src="/assets/958599363857/1*W_bKd7fHb6kBH3uKPqepPg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*W_bKd7fHb6kBH3uKPqepPg.jpeg" /></p>

<p>床が少し湿っていて、天気は曇り。少し前に大雨が降ったようです。到着後すぐに成田空港の大地ゲームを開始（飛行機を降りて入国審査まで約5分かかりました）。</p>

<h4 id="-1505-入国手続き完了荷物受取後空港を出る">~= 15:05 入国手続き完了＋荷物受取後、空港を出る</h4>

<p><img src="/assets/958599363857/1*Xru5o3DBU_GZyTlVW8Wfcw.webp" alt="" loading="lazy" decoding="async" width="937" height="1016" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzciIGhlaWdodD0iMTAxNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Xru5o3DBU_GZyTlVW8Wfcw.png" /></p>

<p><img src="/assets/958599363857/1*oD9JhXDuh47h4aBYxepu7Q.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*oD9JhXDuh47h4aBYxepu7Q.jpeg" /></p>

<p>空港を出たら、エスカレーターで下の階の「鉄道」方向へ進み、「SKYLINER &amp; KEISEI INFORMATION CENTER」のカウンターで、事前にオンラインで購入した<a href="https://www.kkday.com/zh-tw/product/7913-keisei-skyliner-narita-airport-express-ticket?cid=19365" target="_blank">Skyliner 京成電鉄チケット</a>のQRコードを駅員に見せると、次の便の乗車券に交換できます。</p>

<blockquote>
  <p><em>ご注意ください、駅には他の鉄道のインフォメーションセンターもありますので、写真のインフォメーションセンターをご確認ください。</em></p>
</blockquote>

<p><img src="/assets/958599363857/1*yvMJw_HeZ9Mk8qXaFj6gKw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*yvMJw_HeZ9Mk8qXaFj6gKw.jpeg" /></p>

<p><img src="/assets/958599363857/1*3rXtVnwanfORgy2DPDrKAA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*3rXtVnwanfORgy2DPDrKAA.jpeg" /></p>

<p>15:16の便に乗れず、15:42の便に乗るしかありません。</p>

<p>駅には <a href="https://www.jreast.co.jp/zh-CHT/multi/welcomesuica/welcomesuica.html" target="_blank">Welcome Suica (28日以内に使い切り)</a> と通常のSuicaカードのチャージ機があり、電車を待つ間に今回の旅で使う交通費をチャージしておくことができます（<a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E4%BA%AC%E9%98%AA%E7%A5%9E%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-%E4%BA%AC%E9%83%BD%E5%A4%A7%E9%98%AA%E7%A5%9E%E6%88%B68%E6%97%A5%E9%81%8A%E5%85%A8%E7%B4%80%E9%8C%84%E8%88%87%E5%AF%A6%E7%94%A8%E4%BA%A4%E9%80%9A%E4%BD%8F%E5%AE%BF%E6%8C%87%E5%8D%97-76d66c2e34af/#-2" target="_blank">私はiPhoneのSuicaを使っていて便利で簡単でおすすめです！</a>）</p>

<p><img src="/assets/958599363857/1*Rx_dIfNqzUwhc21VzUvIkw.webp" alt="" loading="lazy" decoding="async" width="954" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Rx_dIfNqzUwhc21VzUvIkw.png" /></p>

<p>「京成線」の案内表示に従って改札を通り、対応するホームで待ちます。</p>

<h4 id="-1542-乗車">~= 15:42 乗車</h4>

<p><img src="/assets/958599363857/1*gM-xQihcfGhbEXFv8_uxIg.webp" alt="" loading="lazy" decoding="async" width="949" height="1081" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDkiIGhlaWdodD0iMTA4MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*gM-xQihcfGhbEXFv8_uxIg.png" /></p>

<p>このホームには多くの種類の列車が停車しますので、必ず確認してからご乗車ください。スタッフも車内で案内しますので、チケットを見せて確認してください。<a href="https://www.jreast.co.jp/tc/downloads/pdf/ntrt10_tc.pdf" target="_blank"><strong>成田エクスプレスは全席指定席で自由席はありません</strong></a>。<strong>チケットがない場合は乗車しないでください</strong>。</p>

<p><img src="/assets/958599363857/1*IEQNy3qmUMrm_GaBAFqUTw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*IEQNy3qmUMrm_GaBAFqUTw.jpeg" /></p>

<p>成田エクスプレスの座席は広く、28インチのスーツケースも収納可能です。もし狭いと感じたら、車両の前後のスペースや荷物棚に置くこともできます（取り扱いには注意してください）。</p>

<p><img src="/assets/958599363857/1*Z0UWLv0qvBf77Ue0xfUQ4w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Z0UWLv0qvBf77Ue0xfUQ4w.jpeg" /></p>

<p>天気は曇り。</p>

<h4 id="1623-京成上野駅に到着">16:23 京成上野駅に到着</h4>

<p><img src="/assets/958599363857/1*Z8aKd12JgWIzCE7qtBsgiQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Z8aKd12JgWIzCE7qtBsgiQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*NEojh1UeOaVynhrnp_d7bQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*NEojh1UeOaVynhrnp_d7bQ.jpeg" /></p>

<p>降車後、案内に従って地下道を通り、G銀座線に乗り換え、渋谷方面行きで上野広小路から新橋駅まで行きます。</p>

<h4 id="1650-東京新橋大和ロイネットホテルに到着">16:50 東京新橋大和ロイネットホテルに到着</h4>

<p><img src="/assets/958599363857/1*b1FSV2C8ZsLRq_A_PHnI5Q.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*b1FSV2C8ZsLRq_A_PHnI5Q.jpeg" /></p>

<p><img src="/assets/958599363857/1*09O3hfLEqGKXuUjmv5ALMA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*09O3hfLEqGKXuUjmv5ALMA.jpeg" /></p>

<p>新橋駅から出て少し歩くだけで着くので、とても便利です！</p>

<p>ホテルが提供する無料のアメニティは非常に充実しており、フェイスマスク、入浴剤、耳栓、携帯用マウスウォッシュなどもあります。</p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/jKsZna0d38c" title="東京新橋大和 ROYNET 飯店" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p><img src="/assets/958599363857/1*JXSKiQeoOOtAlQt946SXiw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*JXSKiQeoOOtAlQt946SXiw.jpeg" /></p>

<p>少し前に行った<a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/"><strong>一昨年の広島・岡山旅行</strong></a>で泊まった「<a href="https://www.youtube.com/watch?v=gmwHRihsyXI" target="_blank">リブマックス岡山倉敷駅前ホテル</a>」は、部屋がとても狭く、一人用の部屋にダブルベッドが置かれているような感じでした。</p>

<blockquote>
  <p><em>欠点は小さいことに加え、部屋の冷蔵庫に冷凍機能がないことです。</em></p>
</blockquote>

<p>荷物を置いたらすぐに渋谷へ出発。</p>

<h4 id="1830-渋谷スカイ-入場待ち">18:30 渋谷スカイ 入場待ち</h4>

<p>渋谷スクランブルスクエアの1階で「Shibuya SKY」展望施設へのエレベーターを見つけ、エレベーターに並んで乗った後、係員にQRコードを見せると入場待ちの列に並べます。（入場時にチケットの確認あり）</p>

<p><img src="/assets/958599363857/1*XTalH3d03U4tmBXD-iK5yw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*XTalH3d03U4tmBXD-iK5yw.jpeg" /></p>

<p>ここから渋谷のスクランブル交差点が見えます。</p>

<blockquote>
  <p><em>到着後、まず無料ロッカーに荷物を預けましょう。セルカ棒などの持ち込みは禁止されています。</em></p>
</blockquote>

<p><img src="/assets/958599363857/1*y5jXwXKVIcG5Df9BxPTHew.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*y5jXwXKVIcG5Df9BxPTHew.jpeg" /></p>

<p><img src="/assets/958599363857/1*DcQwikjwYR6G4JQ9c22cIQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*DcQwikjwYR6G4JQ9c22cIQ.jpeg" /></p>

<blockquote>
  <p><a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E6%9D%B1%E4%BA%AC%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-5-%E5%A4%A9%E9%A3%9F%E4%BD%8F%E8%A1%8C%E5%85%A8%E8%A8%98%E9%8C%84%E8%88%87%E5%BF%85%E8%A8%AA%E6%99%AF%E9%BB%9E%E6%8E%A8%E8%96%A6-9da2c51fa4f2/#%E6%B8%8B%E8%B0%B7--shibuya-sky" target="*blank"><em>旧地再訪</em></a> <em>2年前に比べてかなり太りました。</em></p>
</blockquote>

<blockquote>
  <p><em>エスカレーターは両側にあり、上り下りどちらも写真が撮りやすいです。</em></p>
</blockquote>

<p><img src="/assets/958599363857/1*cRbCKPoZF8FPxklnYTtZ0A.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*cRbCKPoZF8FPxklnYTtZ0A.jpeg" /></p>

<p><img src="/assets/958599363857/1*Bzn4qBq4UfpqSXbcf8Gk-A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*Bzn4qBq4UfpqSXbcf8Gk-A.jpeg" /></p>

<p>屋上の夜景ですが、前回に比べて今回は天気が悪く、霧がかかり小雨も降っていました。</p>

<p><img src="/assets/958599363857/1*dinKHMOg-9bNoG3Chn5HWA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*dinKHMOg-9bNoG3Chn5HWA.jpeg" /></p>

<p><img src="/assets/958599363857/1*WNjqJ1VyhKnBzWEgV2lGfg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*WNjqJ1VyhKnBzWEgV2lGfg.jpeg" /></p>

<p>ずっと下に進んでいくと、Barを通り過ぎますが、ここからの景色も良いです：</p>

<p><img src="/assets/958599363857/1*gsgDlAcVwHQ-pG49di-PIQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*gsgDlAcVwHQ-pG49di-PIQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*Hfioo92OP-JnADRbPH4oMA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Hfioo92OP-JnADRbPH4oMA.jpeg" /></p>

<h4 id="1945-渋谷のスクランブル交差点に戻る">19:45 渋谷のスクランブル交差点に戻る</h4>

<p><img src="/assets/958599363857/1*kLQ5R8LmFXiOduVRoXC-Jw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*kLQ5R8LmFXiOduVRoXC-Jw.jpeg" /></p>

<p><img src="/assets/958599363857/1*OOV8P-Wd_qcLWKvUcPdj_A.webp" alt="" loading="lazy" decoding="async" width="1200" height="854" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*OOV8P-Wd_qcLWKvUcPdj_A.png" /></p>

<p>ちょうど『今際の国のアリス』シーズン3の放送が間近なので、シーンを振り返ってみました；体感的に以前よりも人がかなり増えています。</p>

<p><img src="/assets/958599363857/1*nSlNoHtXjCcmZwLJdhK5Wg.webp" alt="" loading="lazy" decoding="async" width="955" height="1222" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTUiIGhlaWdodD0iMTIyMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*nSlNoHtXjCcmZwLJdhK5Wg.png" /></p>

<p>横断歩道を渡って渋谷パルコに向かい、<a href="https://maps.app.goo.gl/B11rcg3MLFRgJLqT8" target="_blank">極味屋</a> に行きました。</p>

<blockquote>
  <p><a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E6%9D%B1%E4%BA%AC%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-5-%E5%A4%A9%E9%A3%9F%E4%BD%8F%E8%A1%8C%E5%85%A8%E8%A8%98%E9%8C%84%E8%88%87%E5%BF%85%E8%A8%AA%E6%99%AF%E9%BB%9E%E6%8E%A8%E8%96%A6-9da2c51fa4f2/#%E6%B8%8B%E8%B0%B7-parco--%E6%A5%B5%E5%91%B3%E5%B1%8B" target="_blank"><em>前回食べて忘れられなかった。</em></a></p>
</blockquote>

<h4 id="2000-渋谷パルコに到着">20:00 渋谷パルコに到着</h4>

<p><img src="/assets/958599363857/1*5UmVsCAy5wcJHCK9h8xQvg.webp" alt="" loading="lazy" decoding="async" width="1400" height="984" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*5UmVsCAy5wcJHCK9h8xQvg.png" /></p>

<p>残念ながら<a href="https://maps.app.goo.gl/B11rcg3MLFRgJLqT8" target="_blank">極味屋</a>は売り切れでした（数日後にまた来ます）、同じグルメ街で別の串揚げ店に入りました。</p>

<h4 id="2015-串カツあらた-渋谷パルコ店-kushikatsu-arata">20:15 <a href="https://maps.app.goo.gl/PTZVZEqdZayWUiap9" target="_blank">串カツあらた 渋谷パルコ店 Kushikatsu Arata</a></h4>

<p><img src="/assets/958599363857/1*cbSR83bqt56GgvT8gTYRQw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*cbSR83bqt56GgvT8gTYRQw.jpeg" /></p>

<p>定番の串揚げ数本と肉増量の串揚げ、それに牛バラ飯一杯とお酒二杯を注文し、合計で¥6,340でした。</p>

<blockquote>
  <p><em>日本風のふわふわした串カツは美味しくて飽きない、牛バラ飯は味がしっかり染みていてお腹にちょうどいい。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>串揚げ店ではキャベツの基本料金（お通し）が別途かかる場合があります</em></strong> <em>。正確な金額は忘れましたが、一人あたり</em> ¥ <em>300円前後と思われます。</em></p>
</blockquote>

<h4 id="2130-c-pla-渋谷">21:30 <a href="https://maps.app.goo.gl/bTwvHKkbxHofxnig6" target="_blank">C-pla 渋谷</a></h4>

<p><img src="/assets/958599363857/1*G0pG6izsdcwUT_Pnfr7xYQ.webp" alt="" loading="lazy" decoding="async" width="950" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*G0pG6izsdcwUT_Pnfr7xYQ.png" /></p>

<p><img src="/assets/958599363857/1*a8oZSBgBI3ZIOftsOxSH5A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*a8oZSBgBI3ZIOftsOxSH5A.jpeg" /></p>

<p>お腹がいっぱいになって駅に戻る途中、とても大きなC-plaガチャガチャ店を通りかかり、中に入って宝探しをしました。</p>

<blockquote>
  <p><em>欲しいものが見つからなければ、撤退！</em></p>
</blockquote>

<h4 id="おやすみ東京">おやすみ！東京</h4>

<p><img src="/assets/958599363857/1*WwT578CuW9uDdF6FEoJogA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*WwT578CuW9uDdF6FEoJogA.jpeg" /></p>

<p>夜食を買ってホテルに戻り休憩する。</p>

<h3 id="day-20914-日--川越日帰り旅行池袋ショッピング">Day 2(09/14 日) — 川越日帰り旅行、池袋ショッピング</h3>

<h4 id="0930-出発まずマクドナルドで朝食--mcdonalds-マクドナルド新橋日比谷口店">09:30 出発、まずマクドナルドで朝食 — <a href="https://maps.app.goo.gl/7kZzxwNhtNjBKdZC9" target="_blank">McDonald’s マクドナルド新橋日比谷口店</a></h4>

<p><img src="/assets/958599363857/1*ylLKnhvJGSh1inGDz4QPXw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ylLKnhvJGSh1inGDz4QPXw.jpeg" /></p>

<p><img src="/assets/958599363857/1*PBCIcEtyaPLO7bcKEr_X9A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*PBCIcEtyaPLO7bcKEr_X9A.jpeg" /></p>

<p>同じパンケーキハムチーズエッグバーガー！</p>

<blockquote>
  <p><em>このマクドナルドは<a href="/posts/z-度旅行記/東京自由行-5日間の観光-グルメ-宿泊情報を徹底解説-9da2c51fa4f2/">前回も来ました</a>。欠点は古く、環境があまり清潔でなく、自動注文機がないことです。</em></p>
</blockquote>

<h4 id="1050-池袋駅に到着山手線に乗る">10:50 池袋駅に到着（山手線に乗る）</h4>

<p><img src="/assets/958599363857/1*1V90DtPc7kU51PnAhjgL8A.webp" alt="" loading="lazy" decoding="async" width="1200" height="663" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY2MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*1V90DtPc7kU51PnAhjgL8A.png" /></p>

<p>東武東上線に乗り換えて川越へ向かいます。</p>

<p><strong>私たちは事前にオンラインで<a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Factivity%2F100464-kawagoe-pass-digital-ticket%2F" target="_blank">川越周遊券（電車＋バス）</a>を購入し、オンラインで有効化ボタンを押して利用時間を開始しました：</strong></p>

<p><img src="/assets/958599363857/1*-RIG2ZudPZbbPykqbqCb0g.webp" alt="" loading="lazy" decoding="async" width="935" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzUiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*-RIG2ZudPZbbPykqbqCb0g.png" /></p>

<p><img src="/assets/958599363857/1*hD_LqigAsv0lTWLS4uI1uA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*hD_LqigAsv0lTWLS4uI1uA.jpeg" /></p>

<p>直接隣の駅事務室に行き、駅員にQRコードを見せるだけでそのまま入出場できます。（座席指定不要）</p>

<h4 id="1100-東武東上線川越特急に乗車--小川町埼玉県方面行き--川越経由">11:00 東武東上線川越特急に乗車 — 小川町（埼玉県）方面行き — 川越経由</h4>

<p><img src="/assets/958599363857/1*3oFkNAprNiko_GHcF4r-3A.webp" alt="" loading="lazy" decoding="async" width="1400" height="976" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*3oFkNAprNiko_GHcF4r-3A.png" /></p>

<h4 id="1126-川越駅に到着">11:26 川越駅に到着</h4>

<p><img src="/assets/958599363857/1*TxaLPPDw4GDqEEWfRnOx7Q.webp" alt="" loading="lazy" decoding="async" width="1200" height="850" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*TxaLPPDw4GDqEEWfRnOx7Q.png" /></p>

<p><img src="/assets/958599363857/1*fnZcZ9Ct4iNfcWq9Kog7jw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*fnZcZ9Ct4iNfcWq9Kog7jw.jpeg" /></p>

<p><img src="/assets/958599363857/1*pxQYLZnHM7-UA6B7RisQnw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*pxQYLZnHM7-UA6B7RisQnw.jpeg" /></p>

<p>同じく一番端の駅事務室から出て、まず観光パンフレットをもらい、一番遠い<a href="https://maps.app.goo.gl/3vVRnikJQL3zYuGi6" target="_blank">氷川神社</a>へバスで向かい、そこから歩いて戻ることにしました。</p>

<p><img src="/assets/958599363857/1*h0c9y56GEfHWTrtP7q8kOQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="848" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*h0c9y56GEfHWTrtP7q8kOQ.png" /></p>

<p>直接二階の歩道橋から出て、バス乗り場へ降りる。</p>

<h4 id="1135-川越バス停でバスを待つ">11:35 川越バス停でバスを待つ</h4>

<p><img src="/assets/958599363857/1*Z92lcpTR1OitKAL3LRVrtw.webp" alt="" loading="lazy" decoding="async" width="1200" height="853" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Z92lcpTR1OitKAL3LRVrtw.png" /></p>

<p>1番線と3番線の両方から多くの電車が氷川神社に向かいますが、最終的には3番線の名01に乗りました。</p>

<blockquote>
  <p><strong><em>「東武</em> バス <em>」と表示されているバスを利用する場合、<a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Factivity%2F100464-kawagoe-pass-digital-ticket%2F" target="_blank">川越周遊券（電車＋バス）</a> を特に引き換える必要はありません。降車時に運転手にQRコード画面を見せるだけでOKです。</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>周遊券を使うときは、乗車時にSuicaをタッチしないでください。</em></strong></p>
</blockquote>

<h4 id="1155-氷川神社に到着">11:55 氷川神社に到着</h4>

<p><img src="/assets/958599363857/1*ebEe1SnjEeYVieePNBdmuw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ebEe1SnjEeYVieePNBdmuw.jpeg" /></p>

<h4 id="氷川神社">氷川神社</h4>

<p><img src="/assets/958599363857/1*ouWflkODbhhc7t8gRUwhwA.webp" alt="" loading="lazy" decoding="async" width="1200" height="865" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ouWflkODbhhc7t8gRUwhwA.png" /></p>

<p><img src="/assets/958599363857/1*9W_Haty-iabNIwCd3m7Hiw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*9W_Haty-iabNIwCd3m7Hiw.jpeg" /></p>

<p>神社は大きくなく、たくさんの風車や風鈴があります。</p>

<p><strong>厄除けの人形流:</strong></p>

<p><img src="/assets/958599363857/1*ZzDJul6maBw4Km4g3ixHeQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ZzDJul6maBw4Km4g3ixHeQ.jpeg" /></p>

<p><strong>風鈴の祈願と絵馬エリア</strong></p>

<p><img src="/assets/958599363857/1*Xj_rvn15hT9p2t9Xte8Q7w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*Xj_rvn15hT9p2t9Xte8Q7w.jpeg" /></p>

<p><img src="/assets/958599363857/1*ZnfYoNsMDNVNt1-pDg-jaQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*ZnfYoNsMDNVNt1-pDg-jaQ.jpeg" /></p>

<h4 id="鯛のおみくじ">鯛のおみくじ</h4>

<p><img src="/assets/958599363857/1*QJZOlovCi13dIiAQuwobDw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*QJZOlovCi13dIiAQuwobDw.jpeg" /></p>

<p><img src="/assets/958599363857/1*0R_KFD3lJnrkfxQTxXt82w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*0R_KFD3lJnrkfxQTxXt82w.jpeg" /></p>

<p><img src="/assets/958599363857/1*U6w5eGph85nVYP5rAAR76w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*U6w5eGph85nVYP5rAAR76w.jpeg" /></p>

<p>いくつかの魚池で自分で鯛を釣っておみくじができますXD　私は赤い一年安鯛を釣りました。</p>

<p><img src="/assets/958599363857/1*FHiQfCIBVx-EY93PQKur-Q.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*FHiQfCIBVx-EY93PQKur-Q.jpeg" /></p>

<p><img src="/assets/958599363857/1*rKug8yofs-uBooqelaIEMQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*rKug8yofs-uBooqelaIEMQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*wA2-rSUSEQ-5ad0L2A2RCw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*wA2-rSUSEQ-5ad0L2A2RCw.jpeg" /></p>

<p>大吉！</p>

<p><img src="/assets/958599363857/1*wPAUnu2NWojn3xDCq2Bb4Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="995" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*wPAUnu2NWojn3xDCq2Bb4Q.png" /></p>

<p><img src="/assets/958599363857/1*W0t4XZQ14zTYCb6k-84daA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*W0t4XZQ14zTYCb6k-84daA.jpeg" /></p>

<p>もし小銭が足りなければ、神社のスタッフに両替をお願いできます。隣にいるボランティアが無料で英語のくじ解説を手伝ってくれます。悪いおみくじを引いた場合は、そのまま神社に結んでおけば厄除けになります。</p>

<h4 id="1245-氷川神社を出発">12:45 氷川神社を出発</h4>

<p>写真を撮りながら一周して、12:45頃に氷川神社を出発し、小江戸の街と吉伊川MOGUMOGU本舗川越店へ向かう準備をしました。</p>

<h4 id="西武--小江戸巡回バス">西武 — 小江戸巡回バス</h4>

<p><img src="/assets/958599363857/1*lbJXQmrjFElNnSoh_Rtc2g.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*lbJXQmrjFElNnSoh_Rtc2g.jpeg" /></p>

<p>待合室でかっこいい観光バスと音楽を見かけました — それは <a href="https://eaglebus.group/co-edo/zh/" target="_blank">西武運輸の小江戸巡回バス</a> です；<strong>東武の周遊券は使えません</strong>。交通系ICカードでの支払いか、西武鉄道発行の「<a href="https://eaglebus.group/co-edo/2025/06/18/ryde0624/" target="_blank">周遊券</a>」の購入が必要です。</p>

<h4 id="1320-チーカワ-モグモグ本舗-川越店">13:20 <a href="https://maps.app.goo.gl/ccQP8s28jfD9iVne6" target="_blank">チーカワ モグモグ本舗 川越店</a></h4>

<p><img src="/assets/958599363857/1*cRVbxgypDnyUhkdduGQrGQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="993" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk5MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*cRVbxgypDnyUhkdduGQrGQ.png" /></p>

<p><img src="/assets/958599363857/1*s1n-pLkMRKHB9LSTegvrsw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*s1n-pLkMRKHB9LSTegvrsw.jpeg" /></p>

<p>入口にはたくさんのかわいい赤ちゃんがいて、川越限定のさつまいもシリーズがあります。</p>

<p><img src="/assets/958599363857/1*f1PB498M6RshUWre7oxG9w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1935" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE5MzUiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*f1PB498M6RshUWre7oxG9w.jpeg" /></p>

<p>終日人数制限は続いていますが、オープン直後ほど混雑していません。私たちは現地でQRコードをスキャンして、次の時間帯13:40を直接予約しました（まだ空きがありました）。確実に利用したい場合は、事前にオンラインで予約することをおすすめします。</p>

<blockquote>
  <p><em>吉伊カワ MOGUMOGU 本舗 川越店 予約、事前抽選 <a href="https://reurl.cc/ekrR5x" target="_blank">整理券サイト(クリック)</a> 。</em></p>
</blockquote>

<blockquote>
  <p><em>ご注意：スマホ1台につきアカウント1つで1人分、1日に1回、1つの時間帯のみ予約可能</em></p>
</blockquote>

<p><strong>13:40 店の前に時間通りに戻り、入場の列に並ぶ</strong></p>

<p><img src="/assets/958599363857/1*NtS_w3kiOP3Z_zdVg45duQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*NtS_w3kiOP3Z_zdVg45duQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*vEMmOWjXOAfNvjloEDclgA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*vEMmOWjXOAfNvjloEDclgA.jpeg" /></p>

<p>商品の在庫は十分にあり、一部の商品はお一人様あたりの購入数量が制限されています。購入時に追加料金でガチャガチャを回すこともできます。</p>

<p><strong>私の戦利品：</strong></p>

<p><img src="/assets/958599363857/1*E4oKILRhstaUJTIRX-912Q.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*E4oKILRhstaUJTIRX-912Q.jpeg" /></p>

<p><img src="/assets/958599363857/1*Ctanxv2irMlgQ0HSQnwMNQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Ctanxv2irMlgQ0HSQnwMNQ.jpeg" /></p>

<blockquote>
  <p><em>さつまいもウサギは垂れ耳で、とてもかわいい！</em></p>
</blockquote>

<blockquote>
  <p><em>商品リストと価格は<a href="https://chiikawamogumogu.shop/collections/nuigurumimasukoxtuto" target="_blank">公式サイト</a>をご覧ください。</em></p>
</blockquote>

<blockquote>
  <p><em>大きなサツマイモウサギ：¥2,970 / 小さなサツマイモジイカワ：¥1,870</em></p>
</blockquote>

<p><strong>他にもミッフィーとスヌーピーの専門店があります</strong></p>

<p><img src="/assets/958599363857/1*8_7sCUHDuYn4_vMIl54Rcg.webp" alt="" loading="lazy" decoding="async" width="1200" height="846" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*8_7sCUHDuYn4_vMIl54Rcg.png" /></p>

<p><img src="/assets/958599363857/1*O9rii8mVXEZKpzy1wGqsuA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*O9rii8mVXEZKpzy1wGqsuA.jpeg" /></p>

<h4 id="道中のお土産店で川越せんべいと黒糖さつまいもスティックを買いました">道中のお土産店で川越せんべいと黒糖さつまいもスティックを買いました</h4>

<p><img src="/assets/958599363857/1*-l022L-y7yY7hAeZpzwOVg.webp" alt="" loading="lazy" decoding="async" width="1200" height="535" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjUzNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*-l022L-y7yY7hAeZpzwOVg.png" /></p>

<blockquote>
  <p><em>シーフードは美味しく、味付けはしっかりしています。黒糖さつまいもスティックは台湾の黒糖さつまいもチップスのスティック版です。</em></p>
</blockquote>

<p>散策を終えて時間は14:00近く、あまりにもお腹が空いて疲れてしまいました。</p>

<h4 id="旧第八十五銀行本店本館"><a href="https://maps.app.goo.gl/y9z4S4ApsRjsREY37" target="_blank">旧第八十五銀行本店本館</a></h4>

<p><img src="/assets/958599363857/1*BpgkEdsDYYvqfpgVuZBKgQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*BpgkEdsDYYvqfpgVuZBKgQ.jpeg" /></p>

<p>古い建物の2階にあるカフェで軽く何か食べてから出発。</p>

<p><img src="/assets/958599363857/1*QcyUQuLZg3kb-TuYqJzERg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1000" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*QcyUQuLZg3kb-TuYqJzERg.png" /></p>

<blockquote>
  <p><em>お腹が空きすぎておらず、時間も遅くなければ、蕎麦のために並んでも食べたいと思ったでしょう。</em></p>
</blockquote>

<p>食事を終えて外のテラスに出て写真を撮る：</p>

<p><img src="/assets/958599363857/1*ndOuiIyVVmYi3e5gCyr2Fw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ndOuiIyVVmYi3e5gCyr2Fw.jpeg" /></p>

<p><strong>ここから一番街の商店街を見渡せます、とても美しいです：</strong></p>

<p><img src="/assets/958599363857/1*4Q0Q_xZ45C5_xCsYbZp-Wg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*4Q0Q_xZ45C5_xCsYbZp-Wg.jpeg" /></p>

<blockquote>
  <p><em>テラスは共用エリアで、利用料金は無料です。</em></p>
</blockquote>

<h4 id="1530-時の鐘">15:30 <a href="https://maps.app.goo.gl/5zsx2vLHKZvrKmp3A" target="_blank">時の鐘</a></h4>

<p>小江戸の商店街を散策しながら時の鐘へ向かう。</p>

<p><img src="/assets/958599363857/1*gqfXKCkDR8r32kbh52lX3w.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*gqfXKCkDR8r32kbh52lX3w.jpeg" /></p>

<p><img src="/assets/958599363857/1*uPy0lTzewXYdF-GwaOSgrw.webp" alt="" loading="lazy" decoding="async" width="959" height="1225" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTkiIGhlaWdodD0iMTIyNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*uPy0lTzewXYdF-GwaOSgrw.png" /></p>

<p>隣の屋台でたこ焼きせんべいを買っておやつにしました。</p>

<h4 id="大正浪漫夢通-商店街"><a href="https://maps.app.goo.gl/nyidMKyz3L48WvNA7" target="_blank">大正浪漫夢通</a> (商店街)</h4>

<p><img src="/assets/958599363857/1*SVz_ZtnmAp_L_yK-DFRJSQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*SVz_ZtnmAp_L_yK-DFRJSQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*gfbr5A94--q0WEdldobPsg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*gfbr5A94--q0WEdldobPsg.jpeg" /></p>

<p>最後に大正ロマン通りを通り、公車で川越駅へ戻り、池袋に向かいました。</p>

<h4 id="1625-川越駅に戻り東武東上線で池袋へ戻る">16:25 川越駅に戻り、東武東上線で池袋へ戻る</h4>

<p><img src="/assets/958599363857/1*geGRZVP6HHBY9TKrjrUSqQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="843" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*geGRZVP6HHBY9TKrjrUSqQ.png" /></p>

<h4 id="1710-池袋駅-パルコ">17:10 池袋駅 パルコ</h4>

<p><img src="/assets/958599363857/1*w50-WxlZgKpVvH5aIQR7BQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="844" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*w50-WxlZgKpVvH5aIQR7BQ.png" /></p>

<p>池袋に戻ったら、まず池袋駅周辺の百貨店を散策しました。ここにはパルコや東武百貨店があり、たくさんのショップがあります。</p>

<h4 id="ギイカワカフェthe-guest-cafe--diner-ikebukuro--ギイカワラーメンchikawa-ramen-pork"><a href="https://maps.app.goo.gl/tGxXYhytPWoMXzY6A" target="_blank">ギイカワカフェ(THE GUEST cafe &amp; diner Ikebukuro)</a> 、 <a href="https://maps.app.goo.gl/Xjj1pvnPpyyvUGH48" target="_blank">ギイカワラーメン(Chikawa Ramen Pork)</a></h4>

<p><img src="/assets/958599363857/1*DrWhK8JSk5XfcqqefpV_jA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*DrWhK8JSk5XfcqqefpV_jA.jpeg" /></p>

<p><img src="/assets/958599363857/1*cbhgmbw3iv1dQ6rB6c0VPA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*cbhgmbw3iv1dQ6rB6c0VPA.jpeg" /></p>

<p>こちらの上階には二軒の吉伊カワレストランがあります。カフェは通りかかった時に予約が全て埋まっており、ラーメンは現地で並べば入店可能です。</p>

<p><strong>並びにはレストランシリーズのジイカワが買える周辺転売店もあります：</strong></p>

<p><img src="/assets/958599363857/1*AsMwLutWXcmRiXED4rVSuA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*AsMwLutWXcmRiXED4rVSuA.jpeg" /></p>

<p><img src="/assets/958599363857/1*cOPdUeltj43X_CKspzfxCg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*cOPdUeltj43X_CKspzfxCg.jpeg" /></p>

<h4 id="1745-牛たん焼き-仙台辺見-池袋パルコ店">17:45 <a href="https://maps.app.goo.gl/PEMEHM7uMc8K5i6c8" target="_blank">牛たん焼き 仙台辺見 池袋パルコ店</a></h4>

<p><img src="/assets/958599363857/1*AInBZ1mRnIZ3T2US8N7r2Q.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*AInBZ1mRnIZ3T2US8N7r2Q.jpeg" /></p>

<p>夕食の時間が近づいていたので、先にデパートで軽く食べようと思い、最終的にParcoで牛タンを食べることにしました。</p>

<blockquote>
  <p><a href="https://www.n-rs.co.jp/brand/menu/en/henmi_menu_1565.pdf" target="_blank"><em>オンラインメニュー：こちらをクリック</em></a></p>
</blockquote>

<h4 id="1800-抽選-翌日のchiikawa-tokyo-station-吉イカワ東京駅-整理券ベビーシリーズを見たい場合">18:00 抽選 翌日のChiikawa TOKYO Station 吉イカワ東京駅 整理券（ベビーシリーズを見たい場合）</h4>

<blockquote>
  <p><a href="https://chiikawa-info.jp/chiikawaland/tokyo/" target="_blank"><em>整理券のサイト：こちら</em></a></p>
</blockquote>

<p><img src="/assets/958599363857/1*tEZULMHIAdtguLKCJzaZDw.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*tEZULMHIAdtguLKCJzaZDw.jpeg" /></p>

<p>Loading 変換中….外れたQQ、とても人気です。</p>

<p><strong>抽選が終わったら食事開始：</strong></p>

<p><img src="/assets/958599363857/1*NKh1itXkvzs63EAiPtCZ6Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*NKh1itXkvzs63EAiPtCZ6Q.jpeg" /></p>

<blockquote>
  <p><em>この店は<a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E5%B1%B1%E9%99%B0%E9%97%9C%E8%A5%BF%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-%E5%B3%B6%E6%A0%B9%E5%87%BA%E9%9B%B2%E6%9D%BE%E6%B1%9F%E9%B3%A5%E5%8F%96%E5%A7%AC%E8%B7%AF%E5%A4%A7%E9%98%AA%E7%A5%9E%E6%88%B67%E6%97%A5%E7%8D%A8%E6%97%85%E5%85%A8%E8%A8%98%E9%8C%84-aacd5f5cacd1/#%E8%A6%93%E9%A3%9F" target="_blank">以前別の場所でテイクアウトしたことがある</a> 。牛タンの食感と味がとても良く、スープは牛肉スープのようで美味しかった！</em></p>
</blockquote>

<h4 id="1900-池袋でショッピング">19:00 池袋でショッピング</h4>

<p>お腹がいっぱいになったので、引き続きショッピングを楽しみます。</p>

<p><img src="/assets/958599363857/1*VJ9rPJWTSgULeGzvtPEMFg.webp" alt="" loading="lazy" decoding="async" width="939" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzkiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*VJ9rPJWTSgULeGzvtPEMFg.png" /></p>

<p><img src="/assets/958599363857/1*BeovdjRzqdZdRxU1086meg.webp" alt="" loading="lazy" decoding="async" width="942" height="1273" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDIiIGhlaWdodD0iMTI3MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*BeovdjRzqdZdRxU1086meg.png" /></p>

<p><img src="/assets/958599363857/1*XAtHfdnJdmXLQGFJxxyHaA.webp" alt="" loading="lazy" decoding="async" width="929" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjkiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*XAtHfdnJdmXLQGFJxxyHaA.png" /></p>

<p>池袋もとても賑やかで、人も多くお店もたくさんあります。</p>

<h4 id="チーカワパーク"><a href="https://maps.app.goo.gl/H9nivHDc5i8ySG18A" target="_blank">チーカワパーク</a></h4>

<p><img src="/assets/958599363857/1*15SBRn2tB_oNRXAztKzWdQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*15SBRn2tB_oNRXAztKzWdQ.jpeg" /></p>

<p>Chiikawa Parkもここにありますが、遅い時間だったためすでに閉まっていました。</p>

<h4 id="1915-サンシャインシティ--ガシャポン池袋本店--世界最大のガシャポンショップ3000台以上">19:15 <a href="https://maps.app.goo.gl/sMrThaudF2VwjBGP8" target="_blank">サンシャインシティ</a> — <a href="https://maps.app.goo.gl/6JgukBwhaJmmoAFQ7" target="_blank">ガシャポン池袋本店 — 世界最大のガシャポンショップ（3000台以上）</a></h4>

<p><img src="/assets/958599363857/1*HFUXnWbMb_i-gSmgTzNdZQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1006" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMDYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*HFUXnWbMb_i-gSmgTzNdZQ.png" /></p>

<p>世界最大のガチャガチャ店まで歩いて、戦利品を探す。</p>

<blockquote>
  <p><em>最後は特に何も買わず、ここは台数は多いものの特別なものはなく、分類もかなり雑で見ていて混乱しました。</em></p>
</blockquote>

<h4 id="2010-池袋駅に戻る--ホテルで休憩">20:10 池袋駅に戻る — ホテルで休憩</h4>

<p><img src="/assets/958599363857/1*N6AmcHvBHP0LeQswh9iXSQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*N6AmcHvBHP0LeQswh9iXSQ.jpeg" /></p>

<p><strong>本日の夜食：</strong></p>

<p><img src="/assets/958599363857/1*pjTtrIIs2qmtQmlun7-P1A.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*pjTtrIIs2qmtQmlun7-P1A.jpeg" /></p>

<p>定番の豆腐皮インスタントラーメン＋コンビニの唐揚げ＋お酒。</p>

<h3 id="day-30915-月--東京駅一番街熱海花火大会">Day 3(09/15 月) — 東京駅一番街、熱海花火大会</h3>

<p>午後14:57発の新幹線で熱海へ向かう予定です。</p>

<p><strong>この日のメインイベント — 熱海花火大会</strong>；朝はゆっくり寝てから出発。</p>

<h4 id="1110-東京駅">11:10 東京駅</h4>

<p><img src="/assets/958599363857/1*pohebZUwh5jI-z7iyBsUfQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1003" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMDMiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*pohebZUwh5jI-z7iyBsUfQ.png" /></p>

<p>昼近くに、まず駅の中で食事を探す。</p>

<p><img src="/assets/958599363857/1*lUVuLvW3e19wluc4X3LupA.webp" alt="" loading="lazy" decoding="async" width="1200" height="865" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*lUVuLvW3e19wluc4X3LupA.png" /></p>

<p><strong>東京駅にも<a href="https://maps.app.goo.gl/vkmPHf4j6SgRGprb8" target="_blank">極味屋</a>がありますが、とても混んでいて、11:00の開店前から多くの人が並んでいます。待ち時間は約1時間ほどと予想されます。</strong></p>

<p>向かいの神戸牛を食べに行く。</p>

<h4 id="kobebeef-daia-tokyo-station-store--神戸牛ダイア-東京駅店"><a href="https://maps.app.goo.gl/K1grYFDpH52WxMkdA" target="_blank">Kobebeef Daia tokyo station store — 神戸牛ダイア 東京駅店</a></h4>

<p><img src="/assets/958599363857/1*67WiU_TZIuxie7OBx31Z6w.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*67WiU_TZIuxie7OBx31Z6w.jpeg" /></p>

<p><img src="/assets/958599363857/1*ybIjFMLqTTSnvUne_N2qwA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ybIjFMLqTTSnvUne_N2qwA.jpeg" /></p>

<blockquote>
  <p><em>懐かしい美味しさ、<a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E5%B1%B1%E9%99%B0%E9%97%9C%E8%A5%BF%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-%E5%B3%B6%E6%A0%B9%E5%87%BA%E9%9B%B2%E6%9D%BE%E6%B1%9F%E9%B3%A5%E5%8F%96%E5%A7%AC%E8%B7%AF%E5%A4%A7%E9%98%AA%E7%A5%9E%E6%88%B67%E6%97%A5%E7%8D%A8%E6%97%85%E5%85%A8%E8%A8%98%E9%8C%84-aacd5f5cacd1/#1700-%E7%A5%9E%E6%88%B8%E7%89%9B-%E5%90%89%E7%A5%A5%E5%90%89" target="_blank">前回神戸に行ったときにも特別に神戸牛を食べに行きました</a>（吉祥吉）、価格は東京が神戸産地より約8,000円高いです（プライム神戸牛サーロイン220g 東京 ¥39,160 / 神戸 ¥31,600）。</em></p>
</blockquote>

<p><img src="/assets/958599363857/1*d8dRk0mNMIBZ2WRlRvxdpQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*d8dRk0mNMIBZ2WRlRvxdpQ.jpeg" /></p>

<p>懐かしい味と同じで、肉はとても柔らかく、異臭もなく牛肉本来の香りだけがします；気づいたらあっという間に食べ終わっていました！</p>

<h4 id="1220-東京駅地下一番街を散策開始">12:20 東京駅地下一番街を散策開始</h4>

<p><img src="/assets/958599363857/1*L0hqu-EQj9j98YtOCGqfWw.webp" alt="" loading="lazy" decoding="async" width="931" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzEiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*L0hqu-EQj9j98YtOCGqfWw.png" /></p>

<p><img src="/assets/958599363857/1*8RfVcL7vNuaLnQ8RTqx77Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="995" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*8RfVcL7vNuaLnQ8RTqx77Q.png" /></p>

<p>地下街は人が多く、ほとんどのIPが揃っています。サンリオ、ワンピース、ジャンプストア、リラックマ、どんぐり共和国、スヌーピー、ちいかわなどです。</p>

<h4 id="ちいかわベビートーキョーステーション"><a href="https://maps.app.goo.gl/ujTHi4i1YM2Jhq7u6" target="_blank">ちいかわベビートーキョーステーション</a></h4>

<p><img src="/assets/958599363857/1*5FO6T-tcqFfmD6qWrHfhTw.webp" alt="" loading="lazy" decoding="async" width="954" height="1201" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTQiIGhlaWdodD0iMTIwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*5FO6T-tcqFfmD6qWrHfhTw.png" /></p>

<p><img src="/assets/958599363857/1*c2ParIuNtMQ0WReypFW_AQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*c2ParIuNtMQ0WReypFW_AQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*14U3tJHvWtVDyF7A2XM3Gg.webp" alt="" loading="lazy" decoding="async" width="1200" height="853" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*14U3tJHvWtVDyF7A2XM3Gg.png" /></p>

<p><a href="https://chiikawa-info.jp/chiikawaland/tokyo/" target="_blank">整理券</a> が当たらず、通り過ぎて写真だけ撮りました。商品の量は十分で、人も少なかったです（むしろ人数制限が緩すぎる感じ？）</p>

<p><img src="/assets/958599363857/1*RhUU4XWAV_mo818lqez6qw.webp" alt="" loading="lazy" decoding="async" width="1200" height="843" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*RhUU4XWAV_mo818lqez6qw.png" /></p>

<p>まだ物足りなければ、隣の大丸百貨店や周辺の他の地下街へ行くこともできます。</p>

<h4 id="1400-東京駅で免税手続きと荷物預け">14:00 東京駅で免税手続きと荷物預け</h4>

<p><img src="/assets/958599363857/1*V1V-6jaK-XgaIJtFUqaUTQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="857" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*V1V-6jaK-XgaIJtFUqaUTQ.png" /></p>

<p>東京駅で買い物をして免税を受ける場合は、直接1階に戻り、東海道・山陽新幹線日本橋口の向かいにある免税カウンターで手続きをしてください。</p>

<p><img src="/assets/958599363857/1*Y0o7PYsSkdhHB0F-pdG6jQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Y0o7PYsSkdhHB0F-pdG6jQ.jpeg" /></p>

<p>いくつか買い物をしましたが、コインロッカーの受付は夜20時までなので、荷物を預けるためにロッカーを探しました。ここにはたくさんのロッカーが利用できます。</p>

<blockquote>
  <p><em>荷物を預けた後、フードコートでいくつか食べ物を買い、移動中に食べる準備をしました。</em></p>
</blockquote>

<h4 id="1430-熱海行きの電車に乗る準備">14:30 熱海行きの電車に乗る準備</h4>

<p><img src="/assets/958599363857/1*PgBfGRbUfgWsyh1i24C8Mw.webp" alt="" loading="lazy" decoding="async" width="947" height="1057" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDciIGhlaWdodD0iMTA1NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*PgBfGRbUfgWsyh1i24C8Mw.png" /></p>

<p>同じく東海道・山陽新幹線の日本橋口から入場します。</p>

<p><img src="/assets/958599363857/1*0PMsHuVFQWeAGUgHwpO7pA.webp" alt="" loading="lazy" decoding="async" width="950" height="1160" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTAiIGhlaWdodD0iMTE2MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*0PMsHuVFQWeAGUgHwpO7pA.png" /></p>

<p><img src="/assets/958599363857/1*OKIhEwPPdSa-tDFMyiHC_A.webp" alt="" loading="lazy" decoding="async" width="854" height="1262" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NTQiIGhlaWdodD0iMTI2MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*OKIhEwPPdSa-tDFMyiHC_A.png" /></p>

<p><a href="https://www.kkday.com/zh-tw/transportation/japan-rail?cid=19365" target="_blank">KKday</a> / <a href="https://affiliate.klook.com/redirect?aid=99683&amp;aff_adid=1134759&amp;k_site=https%3A%2F%2Fwww.klook.com%2Fzh-TW%2Fjapan-rail%2F" target="_blank">Klook</a> で事前に購入した電子チケットは、券売機での引き換え不要で、青い改札機にスマホのQRコードをかざすだけで入場できます。</p>

<p><img src="/assets/958599363857/1*8XhMmWSYamkoIpZcrcexiw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*8XhMmWSYamkoIpZcrcexiw.jpeg" /></p>

<p>改札が成功するとチケットが出てきます（情報確認や車内検札用に便利です）が、入退場はスマホのQRコードを使う必要があります。</p>

<p><img src="/assets/958599363857/1*VjszDJiQ3FvhmPZ6lezlaQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*VjszDJiQ3FvhmPZ6lezlaQ.jpeg" /></p>

<h4 id="1457-東京出発-熱海へ向かう">14:57 東京出発 熱海へ向かう</h4>

<p><img src="/assets/958599363857/1*LtxEb2m13uqztgio8zrwrA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*LtxEb2m13uqztgio8zrwrA.jpeg" /></p>

<p><img src="/assets/958599363857/1*zEZdPMxvFTM1ZdGGClg_SQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*zEZdPMxvFTM1ZdGGClg_SQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*lMSwYOhx4zEClwuaRJqpnw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*lMSwYOhx4zEClwuaRJqpnw.jpeg" /></p>

<p>軽くスナック休憩。</p>

<h4 id="1542-熱海に到着">15:42 熱海に到着</h4>

<p><img src="/assets/958599363857/1*6snvQ0gvBAze0Z4Poh7ywg.webp" alt="" loading="lazy" decoding="async" width="1200" height="868" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*6snvQ0gvBAze0Z4Poh7ywg.png" /></p>

<p><img src="/assets/958599363857/1*bMpYH8-Dvf2iqufVYC1w0w.webp" alt="" loading="lazy" decoding="async" width="954" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*bMpYH8-Dvf2iqufVYC1w0w.png" /></p>

<p><img src="/assets/958599363857/1*ECAXngp1TSBZehMFgTfruw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ECAXngp1TSBZehMFgTfruw.jpeg" /></p>

<p>2025年 熱海海上花火大会へようこそ！</p>

<blockquote>
  <p><em>公式の案内：花火大会終了後は混雑が予想されるため、新幹線のチケットは事前にご購入ください。</em></p>
</blockquote>

<p>新幹線の改札を出た後、在来線の改札も通る必要があります（スタッフにチケットのQRコードを見せるだけで通れます）。</p>

<p><img src="/assets/958599363857/1*MzafXGx-5W__v6ER9L55qg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*MzafXGx-5W__v6ER9L55qg.jpeg" /></p>

<p>天気は曇りですが、日差しが強くないのが良い点です！</p>

<p><img src="/assets/958599363857/1*sfEvxO-r_6o1zXerVBmmxw.webp" alt="栄光の焼肉の道" loading="lazy" decoding="async" width="1200" height="675" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY3NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*sfEvxO-r_6o1zXerVBmmxw.png" /></p>

<p>栄光の焼肉の道</p>

<p><img src="/assets/958599363857/1*7-Gke4s_SdS3Ak7FshhbYw.webp" alt="" loading="lazy" decoding="async" width="948" height="1208" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDgiIGhlaWdodD0iMTIwOCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*7-Gke4s_SdS3Ak7FshhbYw.png" /></p>

<p><img src="/assets/958599363857/1*klSuH4wuVQev1vAE8uhrzg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*klSuH4wuVQev1vAE8uhrzg.jpeg" /></p>

<p><img src="/assets/958599363857/1*NoN8BV-7HvjIqgoMvrNo_Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*NoN8BV-7HvjIqgoMvrNo_Q.jpeg" /></p>

<p>商店街を抜けてまっすぐ下に進むと、海辺に着きます。</p>

<p><img src="/assets/958599363857/1*xsPseN91hTY7i51fJPjcTA.webp" alt="" loading="lazy" decoding="async" width="963" height="1126" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjMiIGhlaWdodD0iMTEyNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*xsPseN91hTY7i51fJPjcTA.png" /></p>

<p><a href="https://maps.app.goo.gl/xZ6QHf3UAWu4iXtD8" target="_blank">ルートは上の地図の通りです</a>。まずLawsonで食べ物と飲み物を買ってから、海辺でピクニックをして花火を待ちます。</p>

<p><img src="/assets/958599363857/1*x0YEr4v70zdBu1cMZyq7zw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*x0YEr4v70zdBu1cMZyq7zw.jpeg" /></p>

<p><img src="/assets/958599363857/1*OSrew6n7pXgiQMkmz6TFrw.webp" alt="" loading="lazy" decoding="async" width="1200" height="880" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg4MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*OSrew6n7pXgiQMkmz6TFrw.png" /></p>

<p>花火は上の地図の位置付近で打ち上げられます。<a href="https://maps.app.goo.gl/XZmFfi3wDBJFERyQ8" target="_blank">Higashikaigancho</a> の後方のビーチまで歩いて待つことができます。ここでは海で遊ぶこともでき、近くに共用トイレやシャワーもあります。（ただし、設備は古くなっている可能性があるので、事前に確認することをおすすめします）</p>

<p><img src="/assets/958599363857/1*93jLDQa0cb1jewFvsazD9Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*93jLDQa0cb1jewFvsazD9Q.jpeg" /></p>

<p>熱海のビーチからは熱海城も遠くに見えます。</p>

<h4 id="1700-熱海サンビーチ">17:00 熱海サンビーチ</h4>

<p><img src="/assets/958599363857/1*MaQ6luHYefGS_EdREO8Z8A.webp" alt="" loading="lazy" decoding="async" width="675" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NzUiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*MaQ6luHYefGS_EdREO8Z8A.jpeg" /></p>

<p>熱海にはそんなに早く着く必要はないと感じました。人は思ったほど多くありません。大体18:30前に来れば、まだ砂浜に場所があります。20:20の花火打ち上げまでいても、見る場所は十分にあります。</p>

<p><img src="/assets/958599363857/1*7TaD649tgt3KS0hfcDNuzg.webp" alt="" loading="lazy" decoding="async" width="1200" height="675" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY3NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*7TaD649tgt3KS0hfcDNuzg.jpeg" /></p>

<h4 id="1800-熱海花火大会-ビーチの人混み">18:00 熱海花火大会 ビーチの人混み</h4>

<p><img src="/assets/958599363857/1*_FH0OfAii22pyLOikGi2Tg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*_FH0OfAii22pyLOikGi2Tg.jpeg" /></p>

<p><img src="/assets/958599363857/1*ET9HOKp_AUG6BXKz9YFRfQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*ET9HOKp_AUG6BXKz9YFRfQ.jpeg" /></p>

<p>18:00でもまだ多くの席があり、または多くの人が先にピクニックマットを敷いて場所取りをし、その後周辺を散策し、花火が始まる直前に戻ってくる様子が見られます。</p>

<p><strong>もう少し奥に進むと、<a href="https://maps.app.goo.gl/fYK3FxCFxZ8oMzRj6" target="_blank">Sky Deckあたり</a> に小さな夜市があり、食べ物を売っています（コスパはあまり良くないです）：</strong></p>

<p><img src="/assets/958599363857/1*ABMNXDPrn2rHZ_BT_q6piA.webp" alt="" loading="lazy" decoding="async" width="1200" height="841" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ABMNXDPrn2rHZ_BT_q6piA.png" /></p>

<p>ビーチ周辺にはトイレもあり、困ることはありません。</p>

<h4 id="2015-花火開始間近のビーチの人混み">20:15 花火開始間近のビーチの人混み</h4>

<p><img src="/assets/958599363857/1*MhEq7Oix6_1SHWcLHWXxLg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*MhEq7Oix6_1SHWcLHWXxLg.jpeg" /></p>

<p><img src="/assets/958599363857/1*GltFsKbSIEPBGCU0tujfHQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*GltFsKbSIEPBGCU0tujfHQ.jpeg" /></p>

<p>後ろ（遊歩道）に人が多いです。</p>

<h4 id="2020-花火大会開始">20:20 花火大会開始</h4>

<p><img src="/assets/958599363857/1*tQkiAdu0D5xhrsRaSwx2ow.webp" alt="" loading="lazy" decoding="async" width="1200" height="675" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY3NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*tQkiAdu0D5xhrsRaSwx2ow.jpeg" /></p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/mI8vaJUpAzY" title="2025/09/15 熱海煙花大會" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p><img src="/assets/958599363857/1*qsOMKdPSeRp3svZjdxg0bw.webp" alt="" loading="lazy" decoding="async" width="1342" height="929" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzQyIiBoZWlnaHQ9IjkyOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*qsOMKdPSeRp3svZjdxg0bw.png" /></p>

<p>花火は複数のパートに分かれており、20:40まで（20分間）続きます。特にお気に入りのパートは、全面に広がる壮大な花火ですが、今日は湿気が多くて後半は煙が少し広がりにくかったです。</p>

<h4 id="2045-退場開始">20:45 退場開始</h4>

<p><img src="/assets/958599363857/1*Is19CY4ydHSl6o_koAwUxw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Is19CY4ydHSl6o_koAwUxw.jpeg" /></p>

<p><img src="/assets/958599363857/1*-Op_qDpZVTPamDHpMjrLGA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*-Op_qDpZVTPamDHpMjrLGA.jpeg" /></p>

<p>帰る人の人混みは非常に多かったですが、皆さん秩序正しくゆっくり駅へ向かっていました。来るときは下り坂で、帰りは上り坂（疲れました）。</p>

<h4 id="2105-熱海駅に戻る">21:05 熱海駅に戻る</h4>

<p><img src="/assets/958599363857/1*0YVBx1LVIM38oZnnFl-uHw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*0YVBx1LVIM38oZnnFl-uHw.jpeg" /></p>

<p><img src="/assets/958599363857/1*AAk3JHAyjLZtD47VozQxhQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="999" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk5OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*AAk3JHAyjLZtD47VozQxhQ.png" /></p>

<p>帰りは人が多く、熱海駅まで戻るのに約20〜25分かかり、改札も非常に混雑しています。もし在来線（ローカル線）を利用する場合は、列に並んでゆっくり改札を通る必要があります。<strong>新幹線のチケットを既に購入している場合は、右側の有人改札を直接通って在来線の上を通り、新幹線乗り場へ行くことができます。</strong></p>

<blockquote>
  <p><em>時間が足りないかと思い、22:02発の熱海から東京行きのチケットを購入しましたが、現地の状況を見ると21:26発の早い便でも十分間に合いました</em></p>
</blockquote>

<h4 id="2120-ホームで待機">21:20 ホームで待機</h4>

<p><img src="/assets/958599363857/1*FlXrgL64tIESh9YANzlCgA.webp" alt="" loading="lazy" decoding="async" width="1400" height="864" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijg2NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*FlXrgL64tIESh9YANzlCgA.png" /></p>

<p><img src="/assets/958599363857/1*P8UbBT810VfOu1d-FjmGfQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*P8UbBT810VfOu1d-FjmGfQ.jpeg" /></p>

<p>新幹線はここがとても広々としていて、エアコンがよく効いています。</p>

<p><img src="/assets/958599363857/1*1yTYNHadfcjXGCssVCOYuQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*1yTYNHadfcjXGCssVCOYuQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*Xh7kHOo5wLCsZq0HsfcxjA.webp" alt="" loading="lazy" decoding="async" width="1200" height="882" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg4MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Xh7kHOo5wLCsZq0HsfcxjA.png" /></p>

<p>リンゴソーダを一本飲んで元気を出したが、他の地域の大雨の影響で、すべての便が遅延した。</p>

<h4 id="2225-乗車約20分遅延">~=22:25 乗車（約20分遅延）</h4>

<p><img src="/assets/958599363857/1*ffvGyMO0-1naq-JFmy9kfw.webp" alt="" loading="lazy" decoding="async" width="941" height="1192" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDEiIGhlaWdodD0iMTE5MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ffvGyMO0-1naq-JFmy9kfw.png" /></p>

<h4 id="-2310-東京到着">~= 23:10 東京到着</h4>

<p>山手線に乗り換えて新橋へ戻る。</p>

<p><img src="/assets/958599363857/1*JUzg76hP_ZQMXHzkFKDmdA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*JUzg76hP_ZQMXHzkFKDmdA.jpeg" /></p>

<h4 id="-2340-ホテルに戻って休憩">~= 23:40 ホテルに戻って休憩</h4>

<p><img src="/assets/958599363857/1*xcMi52GR3TaBBuVYXjAVjg.webp" alt="" loading="lazy" decoding="async" width="1200" height="846" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*xcMi52GR3TaBBuVYXjAVjg.png" /></p>

<p><img src="/assets/958599363857/1*TZma2hnWNg9KTatodIad5w.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*TZma2hnWNg9KTatodIad5w.jpeg" /></p>

<p>充実した一日でした！</p>

<h3 id="day-40916-火--麻布台-teamlab原宿ショッピングカワウソカフェ">Day 4(09/16 火) — 麻布台 Teamlab、原宿ショッピング、カワウソカフェ</h3>

<p>よく寝てからバスに乗って出かける。</p>

<h4 id="1010-到着-麻布台の森">10:10 到着 <a href="https://maps.app.goo.gl/PbjLmES23cBRVRwK6" target="_blank">麻布台の森</a></h4>

<p><img src="/assets/958599363857/1*Vxi-ROH7326xUK1Q_RaSSA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*Vxi-ROH7326xUK1Q_RaSSA.jpeg" /></p>

<p>麻布台の森には <a href="https://maps.app.goo.gl/yyYwwHoZbHBmysqN6" target="_blank">JP Tower</a> だけだと思っていましたが、実は広いエリアに分散した建物群があり、多くの百貨店の店舗や飲食店があります。</p>

<p><img src="/assets/958599363857/1*l04M339xYWoaX0St4PmTGA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*l04M339xYWoaX0St4PmTGA.jpeg" /></p>

<p>まずカフェで朝食を食べて目を覚ます。</p>

<h4 id="1050-teamlab-borderlessへ出発mori-building-digital-art-museum麻布台ヒルズガーデンプラザb棟地下1階">10:50 <a href="https://maps.app.goo.gl/a1VeYdbgBhvPCPXC7" target="_blank">teamLab Borderlessへ出発：MORI Building DIGITAL ART MUSEUM（麻布台ヒルズガーデンプラザB棟地下1階）</a></h4>

<p><img src="/assets/958599363857/1*G2WDXXLUhC1r2oueJDxDcQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*G2WDXXLUhC1r2oueJDxDcQ.jpeg" /></p>

<p>中には地図がありません。すべてを探索したい場合は、外で公式ガイドを入手してください。</p>

<p><img src="/assets/958599363857/1*GKfgsOIo0qXpIshU_0N3UA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*GKfgsOIo0qXpIshU_0N3UA.jpeg" /></p>

<p><img src="/assets/958599363857/1*6BC5_ZTb1w6zcBWf5mNeng.webp" alt="" loading="lazy" decoding="async" width="1200" height="842" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*6BC5_ZTb1w6zcBWf5mNeng.png" /></p>

<p>右に曲がると無料の荷物置き場があり、荷物を置いたらスタッフにチケットを見せて入場できます。</p>

<h4 id="1100-teamlab-borderless">11:00 <a href="https://maps.app.goo.gl/a1VeYdbgBhvPCPXC7" target="_blank">teamLab Borderless</a></h4>

<p><img src="/assets/958599363857/1*ZgsR6mKRK6TjNZkS22p_7A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ZgsR6mKRK6TjNZkS22p_7A.jpeg" /></p>

<p><img src="/assets/958599363857/1*UXRiHpWae9wvx-9kSnGZjQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*UXRiHpWae9wvx-9kSnGZjQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*w3vwhwr_94ICABHOe_z46Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*w3vwhwr_94ICABHOe_z46Q.jpeg" /></p>

<p><img src="/assets/958599363857/1*nMWtkgSZwXV7BDd0PHLNig.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*nMWtkgSZwXV7BDd0PHLNig.jpeg" /></p>

<p><img src="/assets/958599363857/1*kTlH8oGRnbrMmf3L_nWSrg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*kTlH8oGRnbrMmf3L_nWSrg.jpeg" /></p>

<p>teamLabは本当に素晴らしく、さまざまな魔法のようで創造的な場面があり、現実世界には存在しないように感じられます。インタラクションには光と影、鏡面、球体、柱状、葉っぱ、霧などが含まれており、ほぼ360度の全方位シーンで、とても没入感があります。</p>

<blockquote>
  <p><em>地図はなく、すべての展示室は自分で探索する必要があります。女性がスカートを履いている場合、歩いているときに見えないように入口でエプロンを親切に貸し出しています。</em></p>
</blockquote>

<blockquote>
  <p><em>各部屋に入る前にはほぼ必ずスタッフの説明があり、ほとんどの場合「触らないでください」「歩行に注意してください」と案内されます。</em></p>
</blockquote>

<blockquote>
  <p><em>トイレはありますが、案内表示を探すかスタッフに尋ねてください。</em></p>
</blockquote>

<p><img src="/assets/958599363857/1*rOQik1WqrSYIlOlNE8GCNg.webp" alt="" loading="lazy" decoding="async" width="665" height="1182" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NjUiIGhlaWdodD0iMTE4MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*rOQik1WqrSYIlOlNE8GCNg.jpeg" /></p>

<p>写真もとても幻想的です。</p>

<p><img src="/assets/958599363857/1*-QUcAm5LHPzXTaNqzEe-2g.webp" alt="何かを見たということは、別の何かを見ていないということ" loading="lazy" decoding="async" width="1400" height="601" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjYwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*-QUcAm5LHPzXTaNqzEe-2g.png" /></p>

<p>何かを見たということは、別の何かを見ていないということです。</p>

<blockquote>
  <p><em>だいたい12時15分頃まで滞在しましたが、すべて見て回れたとは限りません。お腹が空いていなければ、ここで2〜3時間遊ぶのも問題ないでしょう。</em></p>
</blockquote>

<h4 id="harbs-麻布台の丘店"><a href="https://maps.app.goo.gl/GYvhb3ucV6Xykrtr9" target="_blank">HARBS 麻布台の丘店</a></h4>

<p><img src="/assets/958599363857/1*H3hzyw1S7R8QJqGClj7-Kg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*H3hzyw1S7R8QJqGClj7-Kg.jpeg" /></p>

<p>teamlabを見終わったらすぐ近くにHARBSがあるので、まずはフルーツミルクレープで軽くお腹を満たしました。</p>

<blockquote>
  <p><a href="https://www.harbs.co.jp/zh-TW/allmenu/flag/" target="_blank"><em>オンラインメニュー：こちらをクリックしてください。</em></a></p>
</blockquote>

<p><img src="/assets/958599363857/1*KofxiaB6kF2_MBL4_xSMJA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*KofxiaB6kF2_MBL4_xSMJA.jpeg" /></p>

<p>看板フルーツミルクレープ(Mille Crepes/ミルクレープ) 1カット ￥1,050 ＋ ワンドリンク注文必須。</p>

<blockquote>
  <p><em>中にはメロン（とても甘くて美味しい）＋バナナ＋キウイが入っています。</em></p>
</blockquote>

<h4 id="1320-東京タワー">13:20 東京タワー</h4>

<p><img src="/assets/958599363857/1*bxUphy3A0fYyf5koQkTQNw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*bxUphy3A0fYyf5koQkTQNw.jpeg" /></p>

<p><a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E6%9D%B1%E4%BA%AC%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-5-%E5%A4%A9%E9%A3%9F%E4%BD%8F%E8%A1%8C%E5%85%A8%E8%A8%98%E9%8C%84%E8%88%87%E5%BF%85%E8%A8%AA%E6%99%AF%E9%BB%9E%E6%8E%A8%E8%96%A6-9da2c51fa4f2/#%E6%9D%B1%E4%BA%AC%E9%90%B5%E5%A1%94" target="_blank">前回訪れた際に上ったこともあります <strong>(以前の旅行記をご参照ください)</strong></a>。今回は通り過ぎて写真を撮っただけです。</p>

<p>原宿へ電車で向かいます。</p>

<h4 id="1400-原宿">14:00 原宿</h4>

<p><img src="/assets/958599363857/1*6SJEx_1Xe1cRtxNtxCACUw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*6SJEx_1Xe1cRtxNtxCACUw.jpeg" /></p>

<p>出るとまたまた吉井川が見えました。<a href="https://maps.app.goo.gl/Qo9uS7tVHoRda1MQ7" target="_blank">東急Plaza表参道原宿</a> の上階に<a href="https://maps.app.goo.gl/7rPeXTvCVEtWonMd7" target="_blank">吉井川パン屋</a>があります。</p>

<h4 id="イカワパン店-chiikawa-bakery"><a href="https://maps.app.goo.gl/7rPeXTvCVEtWonMd7" target="_blank">イカワパン店</a> Chiikawa Bakery</h4>

<p><img src="/assets/958599363857/1*z3t6dt_iKNpI2quFtdIylg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*z3t6dt_iKNpI2quFtdIylg.jpeg" /></p>

<p><img src="/assets/958599363857/1*AZPe4DkecEm5YCnjvnokvA.webp" alt="" loading="lazy" decoding="async" width="879" height="1157" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzkiIGhlaWdodD0iMTE1NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*AZPe4DkecEm5YCnjvnokvA.png" /></p>

<p>左側のパンとジャムのお店は整理券が必要ですが、右側のグッズショップは不要です。</p>

<p>（たまたま通りかかっただけなので、中には入りませんでした）</p>

<blockquote>
  <p><a href="https://airwait.jp/WCSP/storeDetail?storeNo=AKR3416883372&amp;langType=KeyTW" target="_blank"><em>こちらをクリックしてオンラインで順番待ち、番号札を受け取る</em></a></p>
</blockquote>

<p><img src="/assets/958599363857/1*W-7h4iIZMQRL6yk5WL7IQQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*W-7h4iIZMQRL6yk5WL7IQQ.jpeg" /></p>

<p>食べ物、パン屋の部分。</p>

<p><img src="/assets/958599363857/1*zPGCxhXve2PB8gO21lFyLg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*zPGCxhXve2PB8gO21lFyLg.jpeg" /></p>

<p><img src="/assets/958599363857/1*AQGlxwc5OIDgwn8dJ62YRw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*AQGlxwc5OIDgwn8dJ62YRw.jpeg" /></p>

<p><img src="/assets/958599363857/1*BAveEbCyszfKzZc3L7CE9w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*BAveEbCyszfKzZc3L7CE9w.jpeg" /></p>

<p>周辺の店舗は品揃えが豊富でしたが、もうさつまいもを買いすぎてしまったので、見るだけにしました。</p>

<h4 id="kiddy-land-キデイランド-原宿店"><a href="https://maps.app.goo.gl/JBGBKiEBNdcycYPz8" target="_blank">Kiddy Land キデイランド 原宿店</a></h4>

<p>出た後、近くの別のKiddy Landにも行ってみました。( <a href="https://www.kiddyland.co.jp/harajuku/" target="_blank">ただし、こちらにはジイカワはありません</a> )</p>

<p><img src="/assets/958599363857/1*WTTkpsTLZ9_35_KVXD01wQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*WTTkpsTLZ9_35_KVXD01wQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*KG4Y3IlpSLIcD-SOBxb4Ug.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*KG4Y3IlpSLIcD-SOBxb4Ug.jpeg" /></p>

<p>スヌーピー、サンリオ、ポケモン、リラックマなど、多くのIPがあります。</p>

<p>散策の時間が15時近くになり、昼はフルーツミルフィーユ一切れだけだったので少しお腹が空いていました。通りかかった評価の高いアメリカンバーガー店に入ってみました。</p>

<h4 id="1450-the-great-burger"><a href="https://maps.app.goo.gl/xgoLanLfSSYFC5jP9" target="_blank">14:50 The Great Burger</a></h4>

<p><img src="/assets/958599363857/1*CxJhjOkE7NSkV2wwiZWlWA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*CxJhjOkE7NSkV2wwiZWlWA.jpeg" /></p>

<p><img src="/assets/958599363857/1*0wzaWAsar2xUmujgMfHVUg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*0wzaWAsar2xUmujgMfHVUg.jpeg" /></p>

<p>特徴は和牛ミニバーガーです。</p>

<p><img src="/assets/958599363857/1*Anb4bgPGloM3oNkV6btS-g.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*Anb4bgPGloM3oNkV6btS-g.jpeg" /></p>

<p><img src="/assets/958599363857/1*2x_JAyGUZmJ58CSR30Rr7A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*2x_JAyGUZmJ58CSR30Rr7A.jpeg" /></p>

<p>味は悪くないですが、食べ過ぎると少し重く感じます。</p>

<h4 id="1540-原宿でショッピング">15:40 原宿でショッピング</h4>

<p>食事の後は原宿で散策を続け、夕方（16:30）に予約したカワウソカフェへ向かいます。</p>

<p><img src="/assets/958599363857/1*sWQbbQUfLq3EWzMhJrvTng.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*sWQbbQUfLq3EWzMhJrvTng.jpeg" /></p>

<p><img src="/assets/958599363857/1*XyVXantdzPWEZA0pYpTXKA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*XyVXantdzPWEZA0pYpTXKA.jpeg" /></p>

<p><img src="/assets/958599363857/1*EfEP8VdYHAbuyxi2C6EFSA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*EfEP8VdYHAbuyxi2C6EFSA.jpeg" /></p>

<p>適当に歩いていたら、前回もここでLe Laboの香水を買ったお店に来ました。2025年日本国内価格 50ml 香水：¥31,350、免税後は約¥28,500です。</p>

<h4 id="1630-harry-harajuku-terrace-カワウソカフェ">16:30 <a href="https://maps.app.goo.gl/WHyJ88K5hRVc4vnk9" target="_blank">HARRY HARAJUKU terrace カワウソカフェ</a></h4>

<p><img src="/assets/958599363857/1*b20FSUf7uuIrFFNRLP6vwQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*b20FSUf7uuIrFFNRLP6vwQ.jpeg" /></p>

<p>この建物の最上階で、隣の階段を使って上がってください。</p>

<p><img src="/assets/958599363857/1*eoDe1nHReBDY4bv070eEBQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*eoDe1nHReBDY4bv070eEBQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*x3phhvrHJ3ocidaw3glJLw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*x3phhvrHJ3ocidaw3glJLw.jpeg" /></p>

<p><img src="/assets/958599363857/1*CpEDCXiZ8Js_st4tzrXtGA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*CpEDCXiZ8Js_st4tzrXtGA.jpeg" /></p>

<p>会場はあまり広くなく、外には3つの池があり、3匹のカワウソが中を歩き回っています。おやつ（¥880）を買って餌やりができます。（手を伸ばしてきます）</p>

<p><img src="/assets/958599363857/1*U30ypE-233jdjvcR0aejGA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*U30ypE-233jdjvcR0aejGA.jpeg" /></p>

<p>コーヒーは自動販売機で自分で押すタイプのコーヒーです。（30分購入で1杯サービス）</p>

<p><img src="/assets/958599363857/1*fBpOYC967t_nalgHfuGCEg.webp" alt="" loading="lazy" decoding="async" width="1200" height="872" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg3MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*fBpOYC967t_nalgHfuGCEg.png" /></p>

<p><img src="/assets/958599363857/1*3dL7ITdswBmvR6KUU9MQSw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*3dL7ITdswBmvR6KUU9MQSw.jpeg" /></p>

<p>中の会場もあまり広くなく、中央に有料のカワウソインタラクティブエリア（追加料金必要）、隣に有料のトトロインタラクティブエリア（追加料金必要）、もう一方には無料のハリネズミインタラクティブエリアと、柵の中にいる数匹のカワウソがいます。</p>

<p><img src="/assets/958599363857/1*L1tbx1lOqgPbpgBmEhGkVA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*L1tbx1lOqgPbpgBmEhGkVA.jpeg" /></p>

<p>私たちは一人あたり¥880を追加して、カワウソと5分間のふれあいをしました。そうでなければ、実際には触ることができません。</p>

<h4 id="1720-カワウソに触れる">17:20 <a href="https://maps.app.goo.gl/WHyJ88K5hRVc4vnk9" target="_blank">カワウソに触れる</a></h4>

<blockquote>
  <p><em>カワウソと触れ合うお客さんが多く、17:20まで順番を待ちました。スタッフが時間を計ってくれます。</em></p>
</blockquote>

<p><img src="/assets/958599363857/1*BNyIXI7P-rccj0dy7yeXeg.webp" alt="" loading="lazy" decoding="async" width="1200" height="704" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjcwNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*BNyIXI7P-rccj0dy7yeXeg.png" /></p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/-h9OupA3kCY" title="HARRY HARAJUKU terrace 水獺咖啡廳 ＨＡＲＲＹ原宿テラス店" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>食べている間にお腹を撫でると、毛がとても柔らかいです。</p>

<blockquote>
  <p><strong><em>全体的に見ると：評価はおそらく2.5〜3つ星くらいでしょう</em></strong></p>
</blockquote>

<blockquote>
  <p><em>全体的にスペースが狭く、1時間あたり¥3,080の基本料金を支払っても、触れ合えるのはハリネズミだけで、他には特に何もありません。コーヒーも自動販売機のみです。スタッフは動物に優しいですが、休憩中の他のカワウソや屋外プールのカワウソが動ける範囲は狭く、少しかわいそうに感じました。</em></p>
</blockquote>

<blockquote>
  <p><em>普通のカフェ店舗の大きさとは少し違い、カワウソが走り回っている。</em></p>
</blockquote>

<p><a href="https://kantenlife.tw/2024/04/18/house-of-otters-japan/#%E6%97%A5%E6%9C%AC%E6%B0%B4%E7%8D%BA%E5%92%96%E5%95%A1%E5%BB%B3%EF%BD%9C%E3%82%AB%E3%83%AF%E3%82%A6%E3%82%BD_%E8%8B%A5%E6%9E%97%E3%81%AE%E5%AE%B6%E3%80%81HARRY_HARAJUKU_terrace%E6%AF%94%E8%BC%83%E5%88%86%E4%BA%AB" target="_blank"><strong>後で調べたら、もう一軒のカワウソ_若林の家のほうが良さそうで、交流時間が長いです。</strong></a></p>

<h4 id="1800-渋谷へ向かう">18:00 渋谷へ向かう</h4>

<p><img src="/assets/958599363857/1*Do_SdWdOCG8ZhXXDVcyEtg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*Do_SdWdOCG8ZhXXDVcyEtg.jpeg" /></p>

<h4 id="1820-極味屋に並ぶtarget_blank">18:20 極味屋に並ぶ{:target=”_blank”}</h4>

<p>まだ時間が早いので、再び渋谷に来て、まずは極味屋で食事。</p>

<p><img src="/assets/958599363857/1*bA7IPZZUq2LVdCbFs9H5lw.webp" alt="" loading="lazy" decoding="async" width="1200" height="861" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*bA7IPZZUq2LVdCbFs9H5lw.png" /></p>

<p>この時間はあまり人がいなかったので、少し並んだだけで食べられました。</p>

<h4 id="1855-着席-極味屋">18:55 着席 <a href="https://maps.app.goo.gl/oZR5RprBErWbkAjq8" target="_blank">極味屋</a></h4>

<p><img src="/assets/958599363857/1*WRCSVqkiXQFWZcMWKs8GPw.webp" alt="" loading="lazy" decoding="async" width="711" height="1220" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MTEiIGhlaWdodD0iMTIyMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*WRCSVqkiXQFWZcMWKs8GPw.png" /></p>

<p><img src="/assets/958599363857/1*hb9il-B-7Hh_BJccl-OfyQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*hb9il-B-7Hh_BJccl-OfyQ.jpeg" /></p>

<p>昼にハンバーグをたくさん食べて飽きてしまい、私は左側の純牛ステーキセットを注文しました。ジュースが美味しかったです。</p>

<blockquote>
  <p><a href="https://zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E6%9D%B1%E4%BA%AC%E8%87%AA%E7%94%B1%E8%A1%8C%E6%94%BB%E7%95%A5-5-%E5%A4%A9%E9%A3%9F%E4%BD%8F%E8%A1%8C%E5%85%A8%E8%A8%98%E9%8C%84%E8%88%87%E5%BF%85%E8%A8%AA%E6%99%AF%E9%BB%9E%E6%8E%A8%E8%96%A6-9da2c51fa4f2/#%E6%B8%8B%E8%B0%B7-parco--%E6%A5%B5%E5%91%B3%E5%B1%8B" target="*blank"><em>前回はハンバーグ＋ステーキセットを食べました</em></a> _、<strong>同じく箸は2膳用意し、鉄の箸で焼き、木の箸で食べます。</strong>*</p>
</blockquote>

<p><strong>看板メニュー — 伊万里ステーキ＋極味屋ハンバーグ牛肉価格：</strong></p>

<ul>
  <li>
    <p>スモール（120g）：¥2,480</p>
  </li>
  <li>
    <p>ミディアム（160g）：¥2,850</p>
  </li>
  <li>
    <p>ラージ（200g）：¥3,180</p>
  </li>
</ul>

<p><strong>純イワリ牛ステーキの価格：</strong></p>

<ul>
  <li>
    <p>ミディアム（130g）：¥2,480円</p>
  </li>
  <li>
    <p>ラージ（180g）：¥3,280円</p>
  </li>
</ul>

<p><strong>アップグレードセット：</strong> ¥450 日本円</p>

<ul>
  <li>
    <p>多湯、サラダ、アイスクリーム</p>
  </li>
  <li>
    <p>個人的には普通だと思います</p>
  </li>
</ul>

<blockquote>
  <p><em>価格が非常にリーズナブルです。</em></p>
</blockquote>

<h4 id="ショッピングドラッグストアでの買い物">ショッピング、ドラッグストアでの買い物</h4>

<p><img src="/assets/958599363857/1*mOCaZv_M3wUL_shhpsklRw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*mOCaZv_M3wUL_shhpsklRw.jpeg" /></p>

<p>デパートで香水売り場を見て、枕用スプレーと一緒に2本買って試してみました。</p>

<p><img src="/assets/958599363857/1*hHziMmw8-TXZgTU96AaLAQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*hHziMmw8-TXZgTU96AaLAQ.jpeg" /></p>

<p>渋谷で食事を終えた後、少し散策してからホテルに戻り、薬局で薬や化粧品を購入しました。ホテルに戻って休憩し、東京に別れを告げる準備をしました。</p>

<p><img src="/assets/958599363857/1*3F0Blw-rzDL6OCLtVJQJtA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*3F0Blw-rzDL6OCLtVJQJtA.jpeg" /></p>

<p><img src="/assets/958599363857/1*p8osyPhc0M_e21JVJLnmbQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*p8osyPhc0M_e21JVJLnmbQ.jpeg" /></p>

<p>肉を食べ過ぎたので、今夜はデザートだけにしましょう！</p>

<blockquote>
  <p><em>同僚が<a href="https://maps.app.goo.gl/ptoRy58awP8gVibR6" target="_blank">原宿 I’m donut? Harajuku</a>でドーナツを買ってきてくれました。（台湾では行列必至ですが、日本では並ばずに買えました）</em></p>
</blockquote>

<h3 id="day-50917-水--上野駅帰路">Day 5(09/17 水) — 上野駅、帰路</h3>

<h4 id="1050-最終チェックアウト前に出発">10:50 最終チェックアウト前に出発</h4>

<p><img src="/assets/958599363857/1*_fnEVTQzT63qUc3tmEtY5A.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*_fnEVTQzT63qUc3tmEtY5A.jpeg" /></p>

<p>さようなら新橋。</p>

<p><img src="/assets/958599363857/1*9iw9U6X2Rih37WcuoITOPw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*9iw9U6X2Rih37WcuoITOPw.jpeg" /></p>

<p>山手線で上野へ行く。</p>

<h4 id="1110-上野駅に到着">11:10 上野駅に到着</h4>

<p><img src="/assets/958599363857/1*O_gvBqPHvCHYXyWu3h2sjw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*O_gvBqPHvCHYXyWu3h2sjw.jpeg" /></p>

<p>特に散策せず、場所が分からなくなるのを避けるため、駅内のコインロッカーで荷物を預けました。</p>

<blockquote>
  <p><em>後で気づきましたが、あまりお得ではありませんでした。荷物を受け取るために改札を通る必要があり、料金もかかりますし、何より経路が不便です。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>後で知ったのですが、Skyliner 京成上野は上野駅の山下口または不忍口の出口付近にあり、駅構内を通って行けるので外に出て日差しを浴びる必要はありません（ただし駅構内は迷いやすいです）。ここで荷物を預ける場合はまた戻ってくる必要があり（約15分）、そちらにも多数のコインロッカーがあります。</em></strong></p>
</blockquote>

<p><img src="/assets/958599363857/1*stvzWK4vvJ2IxguPptM3Bg.webp" alt="" loading="lazy" decoding="async" width="1400" height="980" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*stvzWK4vvJ2IxguPptM3Bg.png" /></p>

<p>ここを出るとすぐに上野動物園があり、左に曲がって、<strong>まずはSkyliner京成上野の座席指定をします。</strong></p>

<p><img src="/assets/958599363857/1*8sL69lXMh1Mzhs05TclHqQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*8sL69lXMh1Mzhs05TclHqQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*R8RkmEqHQLr_405KQIulcg.webp" alt="" loading="lazy" decoding="async" width="946" height="1205" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDYiIGhlaWdodD0iMTIwNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*R8RkmEqHQLr_405KQIulcg.png" /></p>

<p>ついにSkylinerの京成上野駅が見えました。</p>

<p><img src="/assets/958599363857/1*9_ErGzabreeyy-qw0P8zVQ.webp" alt="" loading="lazy" decoding="async" width="945" height="1198" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDUiIGhlaWdodD0iMTE5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*9_ErGzabreeyy-qw0P8zVQ.png" /></p>

<blockquote>
  <p><em>Skylinerは全席指定席のため、早めの予約をおすすめします。</em></p>
</blockquote>

<blockquote>
  <p><em>駅員は中国語を話せます（ただ、最初は彼が中国語を話していると気づきませんでした）。</em></p>
</blockquote>

<p>最後の時間を狙って上野を散策する。</p>

<h4 id="ヨドバシ上野"><a href="https://maps.app.goo.gl/KfAz3oU7DBQpXrUc8" target="_blank">ヨドバシ上野</a></h4>

<p><img src="/assets/958599363857/1*dBKdSU8BqKOanuALBUEesQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*dBKdSU8BqKOanuALBUEesQ.jpeg" /></p>

<p><img src="/assets/958599363857/1*DDnDqOR4o8G6Jg60AospOg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*DDnDqOR4o8G6Jg60AospOg.jpeg" /></p>

<p>隣には二号店もあります。</p>

<h4 id="上野マルイ百貨店まで歩いてショッピング"><a href="https://maps.app.goo.gl/E3EfJWipQzSuC2Uv5" target="_blank">上野マルイ百貨店まで歩いてショッピング</a></h4>

<p><img src="/assets/958599363857/1*O5JJZtfdU1OyJlD1_b8UPw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*O5JJZtfdU1OyJlD1_b8UPw.jpeg" /></p>

<p><img src="/assets/958599363857/1*jmnShS8jUrzCbG0vej3Ksw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*jmnShS8jUrzCbG0vej3Ksw.jpeg" /></p>

<blockquote>
  <p><em>向かい側は上野駅の別の出口で、上野駅は本当に大きいです…</em></p>
</blockquote>

<p><img src="/assets/958599363857/1*Ziu-Golfdiu6XpDVxun10g.webp" alt="" loading="lazy" decoding="async" width="1200" height="1017" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwMTciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*Ziu-Golfdiu6XpDVxun10g.png" /></p>

<p>地理的位置は上の図の通りです。</p>

<h4 id="1200-丸井百貨店を散策する-丸井百貨">12:00 丸井百貨店を散策する <a href="https://maps.app.goo.gl/DvPAhnaEz8HYGSQs7" target="_blank">丸井百貨</a></h4>

<p><img src="/assets/958599363857/1*GsKiVACufVHtpDYxncJ40A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*GsKiVACufVHtpDYxncJ40A.jpeg" /></p>

<p><img src="/assets/958599363857/1*XoxAFbNqAcwJ8YDPjQlQxw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*XoxAFbNqAcwJ8YDPjQlQxw.jpeg" /></p>

<p>2階にはガチャガチャコーナーがあります。</p>

<p><img src="/assets/958599363857/1*37rlYGSdZtckKzwgv9gLWw.webp" alt="" loading="lazy" decoding="async" width="495" height="491" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OTUiIGhlaWdodD0iNDkxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/958599363857/1*37rlYGSdZtckKzwgv9gLWw.png" /></p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/jyFapci9NxY" title="東海道新幹線 チケット音声キーホルダー 新幹線 車票 廣播 扭蛋 Gotcha" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p><a href="https://www.so-ta.com/products_detail/capsuletoy/tokaido_shinkansen/" target="_blank">新幹線の切符ガチャ</a> を回しました。</p>

<p><img src="/assets/958599363857/1*rysyBldMgjEOuR__7hQuOg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*rysyBldMgjEOuR__7hQuOg.jpeg" /></p>

<p>LoftでReFaのハート型マッサージブラシをつい買ってしまいました。</p>

<p><img src="/assets/958599363857/1*sGjazwQmnuqRKWbTubIZXA.webp" alt="" loading="lazy" decoding="async" width="1200" height="857" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*sGjazwQmnuqRKWbTubIZXA.png" /></p>

<p>ここでパンとクロワッサンを食べてお腹を満たしました。</p>

<h4 id="1320-上野駅に戻る">13:20 上野駅に戻る</h4>

<p><img src="/assets/958599363857/1*Ht4JmIU70nKQWu560yEM2A.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Ht4JmIU70nKQWu560yEM2A.jpeg" /></p>

<p>ついでに Sugar Butter Tree をお土産に買いに行きました。</p>

<p>最後に公園口で荷物を受け取り、一周大きく回ってから京成上野に戻りました。</p>

<p><img src="/assets/958599363857/1*oR_x1HqE9qwg094sF-uygA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*oR_x1HqE9qwg094sF-uygA.jpeg" /></p>

<p><img src="/assets/958599363857/1*maLcXgZQHSKZdJB2CQngZg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*maLcXgZQHSKZdJB2CQngZg.jpeg" /></p>

<p>ルートが少し複雑で、先にホームに降りてから別の出口に上がる必要があり、出るとそこがしのばずのくちになります。</p>

<p><img src="/assets/958599363857/1*XLFR3n_fxsGWBK6sU5Lkhw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*XLFR3n_fxsGWBK6sU5Lkhw.jpeg" /></p>

<p>この地下道には多くのコインロッカーがあり、空いています。</p>

<p><img src="/assets/958599363857/1*TyOvYS_0FCfSujRBojgRvg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*TyOvYS_0FCfSujRBojgRvg.jpeg" /></p>

<p>不忍口を出てすぐにSkylinerの京成上野駅があります。（他にもっと近い出口があるかは不明ですが、迷うのを避けてそのまま進みました）</p>

<h4 id="1410-スカイライナー京成上野に戻り成田空港行きの電車に乗る準備をする">14:10 スカイライナー京成上野に戻り、成田空港行きの電車に乗る準備をする</h4>

<p><img src="/assets/958599363857/1*j-oOGCBRflbJWVfkQLrA_Q.webp" alt="" loading="lazy" decoding="async" width="1200" height="873" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg3MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*j-oOGCBRflbJWVfkQLrA_Q.png" /></p>

<h4 id="1420-成田空港へ出発">14:20 成田空港へ出発</h4>

<p><img src="/assets/958599363857/1*vV-Yxbd2JQ9acITed5qGpw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*vV-Yxbd2JQ9acITed5qGpw.jpeg" /></p>

<p><img src="/assets/958599363857/1*-bEzz-shmaBClAhFkmjf8A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*-bEzz-shmaBClAhFkmjf8A.jpeg" /></p>

<p>さっき道でコンビニに寄って、食べ物と飲み物を買って体力を補充しました。</p>

<h4 id="1503-成田空港-第二ターミナル-到着">15:03 成田空港 第二ターミナル 到着</h4>

<p><img src="/assets/958599363857/1*6thsMc0VyilD-DBmtf85Aw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*6thsMc0VyilD-DBmtf85Aw.jpeg" /></p>

<p><img src="/assets/958599363857/1*jaAOzbQTRmETdiie_Vi7Zg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*jaAOzbQTRmETdiie_Vi7Zg.jpeg" /></p>

<p><img src="/assets/958599363857/1*lpge7uQIA81oEOD9JjK3pQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*lpge7uQIA81oEOD9JjK3pQ.jpeg" /></p>

<p>外に出てまっすぐ進むと国際線出発ロビーに到着します。</p>

<blockquote>
  <p><em>もともと一航で<a href="https://matcha-jp.com/tw/25632" target="_blank">新しくオープンしたShake Shackのハンバーガー</a>を食べる予定でしたが、疲れていて行く気になれませんでした。</em></p>
</blockquote>

<h4 id="1540-荷物預け入れ完了">15:40 荷物預け入れ完了</h4>

<p><img src="/assets/958599363857/1*qtNeXNg2HuWhOQBd0YqnyQ.webp" alt="" loading="lazy" decoding="async" width="946" height="1207" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDYiIGhlaWdodD0iMTIwNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*qtNeXNg2HuWhOQBd0YqnyQ.png" /></p>

<blockquote>
  <p><a href="https://digital.jal.co.jp/ssci/identification?lang=zh-tw" target="_blank"><em>出発の24時間前からオンラインチェックインと座席指定が可能で、空港ではすぐに荷物を預けられ、手続きがスムーズになります。</em></a></p>
</blockquote>

<p>荷物を預けたらすぐに出国審査の列に並びました（疲れた）。</p>

<h4 id="1600-セキュリティチェックと出国手続き完了">16:00 セキュリティチェックと出国手続き完了</h4>

<p><img src="/assets/958599363857/1*41hw6bw7XnkIpESE-es7iw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*41hw6bw7XnkIpESE-es7iw.jpeg" /></p>

<p><img src="/assets/958599363857/1*XksioltS7RRgmtf4Gz-N3A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*XksioltS7RRgmtf4Gz-N3A.jpeg" /></p>

<p>数字が小さい方向に進むと、中央の連絡ロビーに到着します。飲食店やショップはすべてここにあります。</p>

<h4 id="まずは-japan-food-hall-b1-で何か食べる">まずは JAPAN FOOD HALL B1 で何か食べる</h4>

<p><img src="/assets/958599363857/1*xj-6KVdDgwx_GPgGF0bHqQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*xj-6KVdDgwx_GPgGF0bHqQ.jpeg" /></p>

<h4 id="1625-食事する">16:25 食事する</h4>

<p><img src="/assets/958599363857/1*Khh3IUrvCCYk1Ccx_fiF7w.webp" alt="" loading="lazy" decoding="async" width="1200" height="842" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*Khh3IUrvCCYk1Ccx_fiF7w.png" /></p>

<p><img src="/assets/958599363857/1*bgttA6-L8uW93zM7TpwOmw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*bgttA6-L8uW93zM7TpwOmw.jpeg" /></p>

<blockquote>
  <p><em>天ぷら海老そばと生ビールを注文しました。</em></p>
</blockquote>

<blockquote>
  <p><em>実際に使ったのは955台湾ドル（空港はやはり高いですね…）</em></p>
</blockquote>

<h4 id="1650-免税店土産物店でショッピング">16:50 免税店、土産物店でショッピング</h4>

<p><img src="/assets/958599363857/1*39UCCUtGuFBVV1FEBQG-9A.webp" alt="" loading="lazy" decoding="async" width="1400" height="921" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjkyMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*39UCCUtGuFBVV1FEBQG-9A.png" /></p>

<p><img src="/assets/958599363857/1*UrCaiyBHekSvy0tzTbM5Gw.webp" alt="" loading="lazy" decoding="async" width="1200" height="848" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*UrCaiyBHekSvy0tzTbM5Gw.png" /></p>

<p><img src="/assets/958599363857/1*_ID9YTxBia4tz-CaQrGcEw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*_ID9YTxBia4tz-CaQrGcEw.jpeg" /></p>

<p><img src="/assets/958599363857/1*DubJNBeqI-tWI5amx_VbbQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*DubJNBeqI-tWI5amx_VbbQ.jpeg" /></p>

<p>成田空港の免税店は本当に何でも揃っています。ブランド品や化粧品、タバコやお酒以外にも、充実したお土産店があり、品揃えが豊富です。価格も外の店舗とほぼ同じか、むしろ安いこともあります。買い忘れがあれば、搭乗前の最後の買い物におすすめです。</p>

<h4 id="1705-le-labo">17:05 Le Labo</h4>

<p><img src="/assets/958599363857/1*J2hChay4G6BPHCItaueHFA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*J2hChay4G6BPHCItaueHFA.jpeg" /></p>

<p>特に探していなかったのですが、成田空港の <a href="https://www.fasola.jp/en/searchByBrand.aspx" target="_blank">Fa-So-La DUTY FREE Cosmetics &amp; Perfumery</a> で偶然Le Laboを見つけました。公式サイトによると、第1・第2ターミナル両方にあります。</p>

<p><img src="/assets/958599363857/1*9XCr-56Q5AlUCDRedP1cBA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*9XCr-56Q5AlUCDRedP1cBA.jpeg" /></p>

<blockquote>
  <p><em>さらに驚いたのは価格で、<strong>50ml — ¥25,700</strong> は日本国内の免税後価格 ¥28,500 よりも安い。</em></p>
</blockquote>

<p><img src="/assets/958599363857/1*ar416ZWoAliERsR_Fg1GJQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ar416ZWoAliERsR_Fg1GJQ.jpeg" /></p>

<p>最後に衝動買いで26〜30ml（空港限定サイズ）を一本購入し、実際の支払いは3,720台湾ドルでした。</p>

<h4 id="1730-搭乗ゲートへ向かい待機">17:30 搭乗ゲートへ向かい待機</h4>

<p><img src="/assets/958599363857/1*5PiE4fENJsi1dynUUL08OQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*5PiE4fENJsi1dynUUL08OQ.jpeg" /></p>

<p>登場口67Bはとても端にあり、遠いです；残念ながら途中の自動販売機で桃の水は全く見かけませんでした。</p>

<p><img src="/assets/958599363857/1*K8V9RnmpGnx--VJ8HTZOaw.webp" alt="" loading="lazy" decoding="async" width="945" height="1202" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDUiIGhlaWdodD0iMTIwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*K8V9RnmpGnx--VJ8HTZOaw.png" /></p>

<h4 id="1750-搭乗東京さようなら">17:50 搭乗、東京さようなら！</h4>

<p><img src="/assets/958599363857/1*OxCGLuV_XrFB_c-BHM10gA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*OxCGLuV_XrFB_c-BHM10gA.jpeg" /></p>

<p><img src="/assets/958599363857/1*0qZy2nb8aXRxB1fmR-uCUA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*0qZy2nb8aXRxB1fmR-uCUA.jpeg" /></p>

<p>機種は BOEING 737–800 で、行きの便と同じです。</p>

<h4 id="成田空港で大混雑本来1810発の予定が結局1900近くまで並んでからの出発になった">成田空港で大混雑、本来18:10発の予定が、結局19:00近くまで並んでからの出発になった</h4>

<p><img src="/assets/958599363857/1*LbcG5trqHcp_4GejuI6iDg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*LbcG5trqHcp_4GejuI6iDg.jpeg" /></p>

<h4 id="日本航空の無料機内wifi">日本航空の無料機内WiFi</h4>

<p><img src="/assets/958599363857/1*1sP5H5jRMsQxm02W2TG6QA.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*1sP5H5jRMsQxm02W2TG6QA.jpeg" /></p>

<p><img src="/assets/958599363857/1*eZ9beWgHlSQufFt-2Mnegg.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*eZ9beWgHlSQufFt-2Mnegg.jpeg" /></p>

<p>機内で無料の1時間WiFiが利用できることを偶然発見しました。</p>

<p><img src="/assets/958599363857/1*jnrR9EmlSy0PcQkKe1eOGA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*jnrR9EmlSy0PcQkKe1eOGA.jpeg" /></p>

<p><img src="/assets/958599363857/1*5CozWE6P0BhIjE6vksu9cQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*5CozWE6P0BhIjE6vksu9cQ.jpeg" /></p>

<p>飛行機の機内食もとても優れていて、カツカレーとデザートのハーゲンダッツでした。</p>

<h4 id="2107-台湾に戻る">21:07 台湾に戻る</h4>

<h4 id="戦利品">戦利品</h4>

<p><img src="/assets/958599363857/1*ILt_i5ONuyBnDnJXMg0BTw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/958599363857/1*ILt_i5ONuyBnDnJXMg0BTw.jpeg" /></p>

<p><img src="/assets/958599363857/1*SUJ70ie42fbD9Y5_LL86Sg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1271" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEyNzEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/958599363857/1*SUJ70ie42fbD9Y5_LL86Sg.jpeg" /></p>

<h4 id="ご覧いただきありがとうございます">ご覧いただきありがとうございます</h4>

<p>今回の東京五日間の旅を一緒に体験していただき、ありがとうございました。この記事の情報が次回の旅行に役立てば幸いです。</p>

<h4 id="その他の旅行記">その他の旅行記</h4>

<ul>
  <li>
    <p><a href="/posts/z-度旅行遊記/釜山自由行-visit-busan-passで8日間の絶景-グルメ満喫ガイド-8ace34a1a3d8/">[旅行記] 2025年 韓国釜山 8日間7泊自由旅行</a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行記/九州自由行-釜山発博多入国の郵輪旅で由布院-大分-福岡を満喫-cb65fd5ab770/">[旅行記] 2024年 九州再訪 9日間自由旅行、釜山経由→博多クルーズ入国</a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/山陰島根出雲松江鳥取関西7日自由行-交通1000km-歩数10万歩の旅程ガイド-aacd5f5cacd1/">[旅行記] 2024 山陰広域エリア 島根 出雲 松江 鳥取 姫路 大阪 神戸 7日間一人旅自由旅行</a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/九州自由行-福岡-長崎-熊本を巡る10日間の独り旅ガイド-d78e0b15a08a/">[旅行記] 2023年 九州 10日間の一人旅</a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/">[旅行記] 2023 広島岡山 6日間自由旅行</a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/名古屋一日快閃自由行-樂桃航空機票攻略と観光スポット紹介-7b8a0563c157/">[旅行記] 9/11 名古屋日帰り弾丸ツアー</a></p>
  </li>
  <li>
    <p>[旅行記] <a href="/posts/z-度旅行記/東京自由行-5日間の観光-グルメ-宿泊情報を徹底解説-9da2c51fa4f2/">2023年 東京 5日間自由旅行</a></p>
  </li>
  <li>
    <p>[旅行記] <a href="/posts/z-度旅行遊記/京阪神自由行-8日間の京都-大阪-神戸旅行完全ガイド-食事-宿泊-交通情報を網羅-76d66c2e34af/">2023 京阪神 8日間自由旅行</a></p>
  </li>
</ul>

<p>*<a href="https://medium.com/ztravel/%E9%81%8A%E8%A8%98-2025-%E6%9D%B1%E4%BA%AC%E5%9C%B0%E5%8D%80-%E5%B7%9D%E8%B6%8A%E5%B0%8F%E6%B1%9F%E6%88%B6%E8%88%87%E7%86%B1%E6%B5%B7%E6%B5%B7%E4%B8%8A%E8%8A%B1%E7%81%AB%E5%A4%A7%E6%9C%83-5-%E6%97%A5%E8%87%AA%E7%94%B1%E8%A1%8C-958599363857" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>を使って変換しました。</p>]]></content>
  </entry><entry>
    <title type="html">LINE Bank入金Firstrade｜手数料150円で即時反映｜口座アップグレード＆手数料補助申請手順</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-%E3%83%A9%E3%82%A4%E3%83%95/line-bank%E5%85%A5%E9%87%91firstrade-%E6%89%8B%E6%95%B0%E6%96%99150%E5%86%86%E3%81%A7%E5%8D%B3%E6%99%82%E5%8F%8D%E6%98%A0-%E5%8F%A3%E5%BA%A7%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89-%E6%89%8B%E6%95%B0%E6%96%99%E8%A3%9C%E5%8A%A9%E7%94%B3%E8%AB%8B%E6%89%8B%E9%A0%86-e4d139fe0685/" rel="alternate" type="text/html" title="LINE Bank入金Firstrade｜手数料150円で即時反映｜口座アップグレード＆手数料補助申請手順" />
    <published>2025-09-02T15:09:54+08:00</published>
    <updated>2026-01-04T11:45:25+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-%E3%83%A9%E3%82%A4%E3%83%95/e4d139fe0685</id><summary type="html">LINE BankからFirstradeへの入金で手数料150円、即時反映を実現。口座アップグレードと約定振替、手数料補助申請の全手順を図解でわかりやすく解説し、スムーズな資金移動をサポートします。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm ライフ" /><category term="ラインバンク" /><category term="ファーストレード" /><category term="ナスダック" /><category term="ライン" /><category term="入金" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/e4d139fe0685/1*u5qqz4o0pCvUTF16sYHNCg.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-%E3%83%A9%E3%82%A4%E3%83%95/line-bank%E5%85%A5%E9%87%91firstrade-%E6%89%8B%E6%95%B0%E6%96%99150%E5%86%86%E3%81%A7%E5%8D%B3%E6%99%82%E5%8F%8D%E6%98%A0-%E5%8F%A3%E5%BA%A7%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89-%E6%89%8B%E6%95%B0%E6%96%99%E8%A3%9C%E5%8A%A9%E7%94%B3%E8%AB%8B%E6%89%8B%E9%A0%86-e4d139fe0685/"><![CDATA[<h3 id="ハンズオンガイド--line-bankからfirstradeへの入金を迅速に手数料はわずか150元口座アップグレード指定振込手数料補助申請の手順">ハンズオンガイド — LINE BankからFirstradeへの入金を迅速に、手数料はわずか150元、口座アップグレード・指定振込・手数料補助申請の手順</h3>

<p>Line Bank 入金 Firstrade およびアカウントアップグレードの約定と手数料補助 完全図解ガイド</p>

<h3 id="line-bank-の利点">LINE Bank の利点</h3>

<ul>
  <li>
    <p>口座開設は簡単：他行の信用情報があれば、ネットで情報入力だけで開設可能です</p>
  </li>
  <li>
    <p>他行振込手数料無料：月最大50回まで</p>
  </li>
  <li>
    <p><strong>痛みなくLINE送金を統合：</strong> 友達同士の送金はiPASS MONEYを使わなくてもOK</p>
  </li>
  <li>
    <p>24時間いつでも為替交換可能</p>
  </li>
  <li>
    <p>多様で柔軟な高金利預金プランを自由に組み合わせて選択可能</p>
  </li>
  <li>
    <p>ローン：スピーディー／統合／10年で楽に返済</p>
  </li>
  <li>
    <p>証券：100元から台湾株に投資可能</p>
  </li>
</ul>

<h4 id="line-bank-米国送金キャンペーン--送金手数料150元受取手数料50元"><a href="https://www.linebank.com.tw/wealth-investment/promotions/10" target="_blank">Line Bank 米国送金キャンペーン — 送金手数料150元、受取手数料50元</a></h4>

<p><strong>[2026/01/01 さらに延長]:</strong></p>

<blockquote>
  <p><em>キャンペーン期間：元のキャンペーン期間は2026/1/1〜2026/6/30</em></p>
</blockquote>

<blockquote>
  <p><em>キャンペーン内容：外国送金手数料割引価格は1件あたりNT$150（通常NT$600）、外貨受取手数料割引価格は1件あたりNT$50（通常NT$400）</em></p>
</blockquote>

<blockquote>
  <p><em>キャンペーン対象商品：外貨送金、外貨受取送金</em></p>
</blockquote>

<p>これは私たちがLINE Bankを利用する最大の魅力です。2026年6月30日までにLINE Bank口座からFirstradeに入金すると、手数料は150元のみで、電信料やその他の費用はかかりません。</p>

<blockquote>
  <p><em>メモ: このキャンペーンは2025年1月から6月に開始され、現在までに2回延長されています（2025年6月から2025年12月、2025年12月から2026年6月に再延長）。<strong>期間をお見逃しなく！</strong></em></p>
</blockquote>

<h4 id="申込みはこちらをクリック"><a href="https://www.linebank.com.tw/R/mgm-portal?campaignId=2&amp;uid=bfQqph" target="_blank">申込みはこちらをクリック</a></h4>

<p><img src="/assets/e4d139fe0685/1*u5qqz4o0pCvUTF16sYHNCg.webp" alt="申込みはこちら" loading="lazy" decoding="async" width="1200" height="632" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjYzMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*u5qqz4o0pCvUTF16sYHNCg.png" /></p>

<p><a href="https://www.linebank.com.tw/R/mgm-portal?campaignId=2&amp;uid=bfQqph" target="_blank">申込はこちら</a></p>

<h4 id="欠点">欠点</h4>

<p>今回は約定口座の設定が必要でしたが、LINE Bankは実店舗の銀行がないため、自然人証明書での認証が必要です。そのため、自然人証明書を取得するために戸籍事務所に行く必要があり、直接銀行に行くより手間がかかります。</p>

<h3 id="firstrade-のメリット">Firstrade のメリット</h3>

<ul>
  <li>
    <p>口座開設、インターフェース、機能がシンプルで、米国株初心者に優しい</p>
  </li>
  <li>
    <p>中国語インターフェース対応</p>
  </li>
  <li>
    <p>取引手数料0円</p>
  </li>
  <li>
    <p>老舗の証券会社</p>
  </li>
</ul>

<blockquote>
  <p><em>口座開設の名前は必ずパスポートの名前を使用してください。</em></p>
</blockquote>

<h4 id="10000ドル以上の入金で最大25ドルの手数料補助を申請可能"><a href="https://www.firstrade.com/zh-TW/accounts/wire-fee-rebate" target="_blank">10,000ドル以上の入金で、最大25ドルの手数料補助を申請可能</a></h4>

<p><img src="/assets/e4d139fe0685/1*-4JN2hY_QP3oZaon2BES0A.webp" alt="入金 $10,000 米ドル以上で、最大 $25 米ドルの手数料補助を申請できます (月最大3回)" loading="lazy" decoding="async" width="464" height="441" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NjQiIGhlaWdodD0iNDQxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*-4JN2hY_QP3oZaon2BES0A.png" /></p>

<p><a href="https://www.firstrade.com/zh-TW/accounts/wire-fee-rebate" target="_blank">10,000ドル以上の入金で、最大25ドルの手数料補助を申請可能</a>（月最大3回）</p>

<blockquote>
  <p>アカウントの準備ができたら、入金を開始できます。</p>
</blockquote>

<h3 id="入金にかかる時間の目安最短2日で入金完了">入金にかかる時間の目安（最短2日で入金完了）</h3>

<p><img src="/assets/e4d139fe0685/1*mhmGifQYaJacIOXwPqIC_A.webp" alt="ここでは私が10月14日にFirstradeに入金し、最終的に送金手数料補助を受け取るまでのタイムラインです。" loading="lazy" decoding="async" width="1200" height="657" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY1NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*mhmGifQYaJacIOXwPqIC_A.png" /></p>

<p>こちらは私が10月14日にFirstradeへ入金し、最終的に送金手数料補助を受け取るまでのタイムラインです。</p>

<ul>
  <li>
    <p>上記はすべて約定口座の紐付けが完了しているか、金額が5万円未満の場合に限ります。初めて約定口座を紐付ける場合は、+2日間の反映待ちが必要です。</p>
  </li>
  <li>
    <p>LINE Bankが受取銀行に送金完了と表示しても、Firstradeに実際に入金されるまで時間差があります。（Firstradeの営業時間内に処理が完了してから「入金完了」と表示されると思われます）</p>
  </li>
  <li>
    <p>Firstradeが入金を受け取った後、送金補助金（1万ドル以上の単一送金）を申請する際にも時間差があります。記録が確認できない場合は、後ほどまたは翌日に再度ご確認ください。</p>
  </li>
</ul>

<h3 id="line-bank-入金-firstrade">LINE Bank 入金 Firstrade</h3>

<p>まず、Line BankからFirstradeへの入金方法を紹介します。</p>

<h4 id="資産をfirstradeに入金する"><a href="https://invest.firstrade.com/cgi-bin/main#/content/customerservice/fundaccount/" target="_blank">資産をFirstradeに入金する</a></h4>

<p><img src="/assets/e4d139fe0685/1*QEJlVLLykQrqTB2UACx95Q.webp" alt="" loading="lazy" decoding="async" width="1015" height="506" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDE1IiBoZWlnaHQ9IjUwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*QEJlVLLykQrqTB2UACx95Q.png" /></p>

<p>(パソコン版を使用) Firstradeにログイン後、以下を選択してください：</p>

<ol>
  <li>
    <p>カスタマーサービス</p>
  </li>
  <li>
    <p>アカウントへの入金</p>
  </li>
</ol>

<blockquote>
  <p><em>もしページが英語の場合は、上部で「繁体字中国語」を選んで言語を変更できます。</em></p>
</blockquote>

<h4 id="送金情報の取得"><a href="https://invest.firstrade.com/scripts/fundmgt/wire_instruction/" target="_blank">送金情報の取得</a></h4>

<p><img src="/assets/e4d139fe0685/1*66aA2JSjEWOLHdj4P6JwVA.webp" alt="" loading="lazy" decoding="async" width="1000" height="426" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAwIiBoZWlnaHQ9IjQyNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*66aA2JSjEWOLHdj4P6JwVA.png" /></p>

<p>「送金」→「送金情報」を選択すると、PDFファイルが開きます。このファイルを保存しておくと、後で入金時に便利です：</p>

<p><img src="/assets/e4d139fe0685/1*11qj5ItxI9rxNrOqCVBw8g.webp" alt="" loading="lazy" decoding="async" width="781" height="1109" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3ODEiIGhlaWdodD0iMTEwOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*11qj5ItxI9rxNrOqCVBw8g.png" /></p>

<ol>
  <li>
    <p>受取銀行情報 — SWIFTコード</p>
  </li>
  <li>
    <p>受取人名義</p>
  </li>
  <li>
    <p>受取人の英語住所</p>
  </li>
  <li>
    <p>受取人の口座番号</p>
  </li>
  <li>
    <p><strong>追記</strong></p>
  </li>
</ol>

<h4 id="line-bankアプリ--海外送金">LINE Bankアプリ — 海外送金</h4>

<p><img src="/assets/e4d139fe0685/1*8zCXdiJWyPNCFW_NuIKNhQ.webp" alt="" loading="lazy" decoding="async" width="683" height="749" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2ODMiIGhlaWdodD0iNzQ5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*8zCXdiJWyPNCFW_NuIKNhQ.png" /></p>

<ol>
  <li>
    <p>「もっと見る」をクリックしてください</p>
  </li>
  <li>
    <p>下にスクロールして「外貨」セクションを見つけ、「海外送金」をクリックしてください。</p>
  </li>
  <li>
    <p>引き落とし金額は「台湾ドルまたは米ドル」を選択し、送金したい金額を入力してください。<br />
<strong>まずは下記のLine Bank口座アップグレードと指定口座の紐付け手順をご参照ください。</strong><br />
<strong>まずは下記のLine Bank口座アップグレードと指定口座の紐付け手順をご参照ください。</strong><br />
<strong>まずは下記のLine Bank口座アップグレードと指定口座の紐付け手順をご参照ください。</strong><br />
<strong>そうしないと1万台湾ドルまでしか送金できません。</strong></p>
  </li>
  <li>
    <p>「送金へ進む」をクリックしてください</p>
  </li>
</ol>

<h4 id="手数料率20260630まで一律150円">手数料率（2026/06/30まで一律150円）</h4>

<ul>
  <li>
    <p>送金 NTD $10,000 / 手数料 NTD $150 = 1.5%</p>
  </li>
  <li>
    <p>送金 NTD $50,000 / 手数料 NTD $150 = 0.3%</p>
  </li>
  <li>
    <p>送金 NTD $300,000 / 手数料 NTD $150 = 0.05%</p>
  </li>
  <li>
    <p>送金 NTD $500,000 / 手数料 NTD $150 = 0.03%</p>
  </li>
</ul>

<blockquote>
  <p><em>一度の送金額が多いほど割合は低くなります。<strong>Firstradeへの単一入金が$10,000米ドル（約310,000台湾ドル）を超える場合、最大$25米ドル、月3回までの入金手数料補助を申請できます。申請は送金後30日以内に行う必要があります（詳細は記事末の解説を参照）。</strong></em></p>
</blockquote>

<h4 id="振込情報の入力">振込情報の入力</h4>

<p><img src="/assets/e4d139fe0685/1*5Bc1Gogt-HJRVdh_ygOPbg.webp" alt="" loading="lazy" decoding="async" width="791" height="789" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3OTEiIGhlaWdodD0iNzg5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*5Bc1Gogt-HJRVdh_ygOPbg.png" /></p>

<p><strong>前のステップで<a href="https://invest.firstrade.com/scripts/fundmgt/wire_instruction/" target="_blank">送金メッセージ</a>の情報を入力：</strong></p>

<ol>
  <li>
    <p>受取人の英語名義： <code class="language-plaintext highlighter-rouge">Apex Clearing Corporation</code></p>
  </li>
  <li>
    <p>受取銀行情報 — SWIFTコードを直接入力すると自動で反映されます</p>
  </li>
  <li>
    <p>検索入力：<code class="language-plaintext highlighter-rouge">HATRUS44</code></p>
  </li>
  <li>
    <p>最初のものを選択してください：<code class="language-plaintext highlighter-rouge">HATRUS44 — BMO Bank N.A CHICAGO</code></p>
  </li>
  <li>
    <p>受取人アカウント番号： <code class="language-plaintext highlighter-rouge">1617711</code> <strong>（変更される可能性がありますので、実際の情報をご確認ください）</strong></p>
  </li>
</ol>

<p><strong>下にスクロールして入力を続けてください：</strong></p>

<p><img src="/assets/e4d139fe0685/1*i2kQnOFRD-azviSj3fCfyA.webp" alt="" loading="lazy" decoding="async" width="358" height="762" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNTgiIGhlaWdodD0iNzYyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*i2kQnOFRD-azviSj3fCfyA.png" /></p>

<ol>
  <li>
    <p>受取人の身分：<code class="language-plaintext highlighter-rouge">民間（法人、個人）</code></p>
  </li>
  <li>
    <p>受取人の英語住所 — 国：<code class="language-plaintext highlighter-rouge">United States</code> を選択してください</p>
  </li>
  <li>
    <p>受取人の英語住所 — 市区町村：<code class="language-plaintext highlighter-rouge">Texas</code> と記入してください</p>
  </li>
  <li>
    <p>受取人の英語住所 — 詳細住所：<code class="language-plaintext highlighter-rouge">One Dallas Center 350 N. St Paul, Suite 1300, Dallas, TX 75201</code>（前のステップの送金情報を参照）</p>
  </li>
  <li>
    <p><strong>⭐️️️️️️ 最も重要なメッセージ欄は必ず記入してください</strong><br />
<strong>⭐️️️️️️ 最も重要なメッセージ欄は必ず記入してください</strong><br />
<strong>⭐️️️️️️ 最も重要なメッセージ欄は必ず記入してください</strong><br />
<strong>前のステップの送金情報を参考に入力してください：</strong> <code class="language-plaintext highlighter-rouge">8桁の口座番号 + 口座名義</code><br />
上図のように： <code class="language-plaintext highlighter-rouge">12345678 ZXXXG CXXXG LI</code></p>
  </li>
  <li>
    <p>「次へ」をクリックしてください</p>
  </li>
</ol>

<h4 id="送金の性質">送金の性質</h4>

<p><img src="/assets/e4d139fe0685/1*jrDAKxcP5jxjHQ41Wf5LWQ.webp" alt="" loading="lazy" decoding="async" width="841" height="794" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NDEiIGhlaWdodD0iNzk0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*jrDAKxcP5jxjHQ41Wf5LWQ.png" /></p>

<ul>
  <li>
    <p>「262 投資国外株式証券」を選択してください。</p>
  </li>
  <li>
    <p>「同意」をクリックして注意事項を申告してください</p>
  </li>
</ul>

<h4 id="送金確認">送金確認</h4>

<p><img src="/assets/e4d139fe0685/1*yiYOU7hagogCvHF1AUxEHQ.webp" alt="" loading="lazy" decoding="async" width="743" height="686" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NDMiIGhlaWdodD0iNjg2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*yiYOU7hagogCvHF1AUxEHQ.png" /></p>

<p>最後のステップとして、情報が正しく入力されているか特に受取人の口座情報と<strong>メッセージ欄</strong>を確認してください。</p>

<ul>
  <li>
    <p>60秒以内に取引内容が確認できない場合、為替レートの見積もりが更新されることがあります。</p>
  </li>
  <li>
    <p>問題なければ「次へ」をクリックして <strong>送金申請を完了してください</strong></p>
  </li>
</ul>

<h4 id="完了">完了</h4>

<p><img src="/assets/e4d139fe0685/1*jaADV3k1wdNZuz2zpogLQA.webp" alt="" loading="lazy" decoding="async" width="869" height="1884" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjkiIGhlaWdodD0iMTg4NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*jaADV3k1wdNZuz2zpogLQA.jpeg" /></p>

<p>この画面が表示されたら、送金申請が完了しています。入金通知が届くまでお待ちください。</p>

<blockquote>
  <p><em>この記事の画像にある送金金額は参考用です。（画像によっては5万円や10万円の場合があります）</em></p>
</blockquote>

<h3 id="line-bankからfirstradeへの送金進捗確認">LINE BankからFirstradeへの送金進捗確認</h3>

<p><img src="/assets/e4d139fe0685/1*nEUD0C8nOO1E2uS9p6u8rw.webp" alt="" loading="lazy" decoding="async" width="1114" height="774" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTE0IiBoZWlnaHQ9Ijc3NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*nEUD0C8nOO1E2uS9p6u8rw.png" /></p>

<p>LINE Bankアプリの右上の通知から、外貨送金通知を見つけて、タップして送金状況を確認できます。</p>

<ul>
  <li>
    <p>平日なら最短で当日に送金が完了しますが、休日の場合は2営業日後まで処理されません。</p>
  </li>
  <li>
    <p><strong>受取人情報を誤って入力すると受取拒否され、返金手数料を支払って再送金が必要になります</strong></p>
  </li>
</ul>

<h4 id="送金申請書取引記録振込明細">送金申請書（取引記録／振込明細）</h4>

<p><img src="/assets/e4d139fe0685/1*EH8g25Pxoewchc5gt7qK_w.webp" alt="" loading="lazy" decoding="async" width="1179" height="2556" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTc5IiBoZWlnaHQ9IjI1NTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/e4d139fe0685/1*EH8g25Pxoewchc5gt7qK_w.jpeg" /></p>

<p><img src="/assets/e4d139fe0685/1*DMrWpw9JdcFVOYuEWgNmkw.webp" alt="" loading="lazy" decoding="async" width="790" height="1031" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3OTAiIGhlaWdodD0iMTAzMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*DMrWpw9JdcFVOYuEWgNmkw.png" /></p>

<p>Line Bankアプリの進捗確認通知（前述の通り）で、下にスクロールすると「振込明細/取引証明書申請」ボタンがあります。これをクリックすると振込明細があなたのメールに送信され、身分証番号でファイルを開いて確認できます。</p>

<h4 id="受取銀行は入金を受け取ったがfirstradeで資金が確認できない">受取銀行は入金を受け取ったがFirstradeで資金が確認できない？</h4>

<p>これは正常です。Line Bank上で送金状況が「受取銀行が入金を受領済み」と表示されて送金完了となっていても、Firstrade側では米国の営業日（時間）になるまで入金確認がされません。</p>

<p>上記の図のように、8月27日午前9時には入金が確認されていましたが、Firstradeが資金を確認し、入金通知メールを受け取ったのは8月28日午前2時10分でした：</p>

<p><img src="/assets/e4d139fe0685/1*7g0qrnxcoE5aYYz0erJrpw.webp" alt="" loading="lazy" decoding="async" width="625" height="715" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MjUiIGhlaWdodD0iNzE1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*7g0qrnxcoE5aYYz0erJrpw.png" /></p>

<p>この時点でFirstradeにログインすると資金が入金されているのが確認でき、米国株の取引を開始できます：</p>

<p><img src="/assets/e4d139fe0685/1*83_EXDsxQpwqgfmkHogYbw.webp" alt="" loading="lazy" decoding="async" width="980" height="704" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5ODAiIGhlaWdodD0iNzA0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*83_EXDsxQpwqgfmkHogYbw.png" /></p>

<p>「マイアカウント」→「アカウント履歴」でも入金記録を確認できます。</p>

<h3 id="line-bank-アカウントアップグレードと約定口座の紐付け方法">Line Bank アカウントアップグレードと約定口座の紐付け方法</h3>

<p><img src="/assets/e4d139fe0685/1*ZbYDlcVZlCEE4fdKgeaWWQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="410" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQxMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*ZbYDlcVZlCEE4fdKgeaWWQ.png" /></p>

<p><strong>権益比較：</strong></p>

<ul>
  <li>
    <p>（口座開設後すぐに利用可能）基本アカウント：1回あたり最大1万ドル、1日あたり最大3万ドル、1か月あたり最大5万ドル。</p>
  </li>
  <li>
    <p>（カスタマーサポートのビデオ通話後）アカウントアップグレード：1回の送金上限5万ドル、1日の上限10万ドル、1ヶ月の上限20万ドル。</p>
  </li>
  <li>
    <p>（自然人認証＋カスタマーサポートのビデオ通話後）約定口座：単一取引の上限は50万ドル。</p>
  </li>
</ul>

<h4 id="line-bank-アカウントのアップグレード">Line Bank アカウントのアップグレード</h4>

<p>実際には他の銀行の基本限度額を引き上げるだけです。 <strong>（このステップではマイナンバーカードは不要です。）</strong></p>

<p><img src="/assets/e4d139fe0685/1*aFqGx67be74ZZr75wUvT-w.webp" alt="" loading="lazy" decoding="async" width="1117" height="779" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTE3IiBoZWlnaHQ9Ijc3OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*aFqGx67be74ZZr75wUvT-w.png" /></p>

<p>LINE Bankアプリを開き、「もっと見る」から下にスクロールして「その他」→「口座アップグレード」を見つけ、アップグレードする口座タイプを選択 → <strong>2. ビデオ認証「認証開始 &gt;」を選択。</strong></p>

<ul>
  <li>
    <p>まず、ネットワークが正常かつ安定していることを確認してください。</p>
  </li>
  <li>
    <p>現在ビデオ通話が利用可能であることを確認してください。</p>
  </li>
</ul>

<p>クリックするとカスタマーサポートにビデオ通話がかかります。サポート担当者とビデオ通話で会話し、口座情報（例えば現在の残高など）を確認されることがあります。確認が終われば、口座のアップグレードが完了します。</p>

<h3 id="firstradeへの送金口座の登録">Firstradeへの送金口座の登録</h3>

<p>おすすめは、Firstradeの送金口座を直接約定口座として登録する方法です。これにより、便利で迅速かつ安全に送金できます。</p>

<ul>
  <li>
    <p>約定口座は2日後に有効になります</p>
  </li>
  <li>
    <p>約定口座はまずマイナンバーカードでの認証が必要です</p>
  </li>
  <li>
    <p><strong>本人確認はTP07で始まるNFCチップ搭載カードのみ対応しています</strong></p>
  </li>
</ul>

<h4 id="自然人認証カードの申請">自然人認証カードの申請</h4>

<p>まずはオンラインで<a href="https://moica.nat.gov.tw/rac_form.html" target="_blank">自然人申請フォームの記入を完了してください</a>：</p>

<p><img src="/assets/e4d139fe0685/1*4xi8pHeUNAPZKijWiXfj1Q.webp" alt="自然人申請フォーム" loading="lazy" decoding="async" width="727" height="1237" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MjciIGhlaWdodD0iMTIzNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*4xi8pHeUNAPZKijWiXfj1Q.png" /></p>

<p><a href="https://moica.nat.gov.tw/rac_form.html" target="_blank">自然人申請フォーム</a></p>

<p>送信後、7日以内にどの市区町村の戸籍事務所（本籍地でなくても可）窓口でも手続きが可能です。</p>

<ul>
  <li>
    <p><strong>手数料：250元</strong></p>
  </li>
  <li>
    <p>現地で手続き、現地で受け取り</p>
  </li>
  <li>
    <p>戸籍事務所でのマイナンバーカード申請者は少なく、昼休みは通常ありません。</p>
  </li>
</ul>

<p><img src="/assets/e4d139fe0685/1*zrmIss8K7vrn18f_CGffDg.webp" alt="" loading="lazy" decoding="async" width="1200" height="873" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg3MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*zrmIss8K7vrn18f_CGffDg.png" /></p>

<h4 id="line-bankでfirstradeの海外送金口座を新規登録する方法">Line BankでFirstradeの海外送金口座を新規登録する方法</h4>

<p><img src="/assets/e4d139fe0685/1*Mi9tRTDMpubsVfWF6AXidg.webp" alt="" loading="lazy" decoding="async" width="1127" height="767" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTI3IiBoZWlnaHQ9Ijc2NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*Mi9tRTDMpubsVfWF6AXidg.png" /></p>

<p>LINE Bankアプリを開く → 「もっと見る」 → 下にスクロールして外貨を見つけ、「マイ送金履歴」をタップ → 「送金指定口座」 → 「指定口座を追加」。</p>

<h4 id="初回利用--アカウント認証の完了">初回利用 — アカウント認証の完了</h4>

<p><img src="/assets/e4d139fe0685/1*nLPxsTJ1ALuv4hLZPcdqmw.webp" alt="" loading="lazy" decoding="async" width="1179" height="1199" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTc5IiBoZWlnaHQ9IjExOTkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/e4d139fe0685/1*nLPxsTJ1ALuv4hLZPcdqmw.jpeg" /></p>

<p>初回の紐付けには「マイナンバーカード認証」と「ビデオ認証」が必要で、ビデオ認証はアカウントアップグレード時にカスタマーサポートとビデオ通話でアカウント情報の確認を行います。</p>

<p><strong>自然人カードの場合は、先ほど申請した自然人カードを使ってカード認証を完了させる必要があります：</strong></p>

<p><img src="/assets/e4d139fe0685/1*-N0scmyLMlqgPHbuDpmD-Q.webp" alt="" loading="lazy" decoding="async" width="1200" height="579" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU3OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*-N0scmyLMlqgPHbuDpmD-Q.png" /></p>

<blockquote>
  <p><em>自然人認証カードの読み取り範囲はやや狭いため、何度か試してようやく成功しました。iPhoneのカメラ中央をカードの中央に合わせ、カードを左右に少し動かしながら数回試すと認証が成功します。</em></p>
</blockquote>

<h4 id="約定口座の追加">約定口座の追加</h4>

<p><img src="/assets/e4d139fe0685/1*RvHTvjTzjap4M09RG5Q8xQ.webp" alt="" loading="lazy" decoding="async" width="749" height="765" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NDkiIGhlaWdodD0iNzY1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*RvHTvjTzjap4M09RG5Q8xQ.png" /></p>

<p>口座情報は前述の送金情報と同じ順序で入力し、間違いがなければ「次へ」をクリックしてください。</p>

<p><img src="/assets/e4d139fe0685/1*2VbwWyl9zQCY9p2fVVoL2w.webp" alt="" loading="lazy" decoding="async" width="1143" height="786" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQzIiBoZWlnaHQ9Ijc4NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*2VbwWyl9zQCY9p2fVVoL2w.png" /></p>

<p>二段階認証のために、届いたばかりのSMSに記載された4桁の認証コードを入力してください。1〜2分ほど待つと、認証成功の確認メッセージが届き、認証が完了します。</p>

<p><img src="/assets/e4d139fe0685/1*WmXzGCmOWMkOxwMhYJ-mfQ.webp" alt="" loading="lazy" decoding="async" width="715" height="791" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MTUiIGhlaWdodD0iNzkxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*WmXzGCmOWMkOxwMhYJ-mfQ.png" /></p>

<p>認証に成功すると、約定口座の登録が完了します！</p>

<ul>
  <li>
    <p>追加した直後、右上に感嘆符が表示され、有効になっていないことを示します。</p>
  </li>
  <li>
    <p><strong>反映されるまでに2日かかります。</strong></p>
  </li>
</ul>

<h4 id="line-bank-firstrade-約定口座からの送金">Line Bank Firstrade 約定口座からの送金</h4>

<p><img src="/assets/e4d139fe0685/1*TfcH3RFr1wR7XKjKjqnvJQ.webp" alt="" loading="lazy" decoding="async" width="740" height="766" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NDAiIGhlaWdodD0iNzY2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*TfcH3RFr1wR7XKjKjqnvJQ.png" /></p>

<p>「私の送金記録」→「送金約定口座」→口座を選択→金額を入力→「約定口座から送金」を選択→情報が自動で入力されます。</p>

<h3 id="firstrade-手数料補助申請方法">Firstrade 手数料補助申請方法</h3>

<ul>
  <li>
    <p>送金金額の条件：<strong>1回の送金</strong>が10,000米ドルを超えること</p>
  </li>
  <li>
    <p>補助金額の上限：25ドル</p>
  </li>
  <li>
    <p>回数制限：月最大3回まで</p>
  </li>
  <li>
    <p>申請期間：送金後30日以内に申請してください</p>
  </li>
</ul>

<p><img src="/assets/e4d139fe0685/1*TFU213ZsLmlrAt7Wj7Vmtw.webp" alt="" loading="lazy" decoding="async" width="1032" height="450" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDMyIiBoZWlnaHQ9IjQ1MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*TFU213ZsLmlrAt7Wj7Vmtw.png" /></p>

<p><img src="/assets/e4d139fe0685/1*JbqxnPqZkNsZuqvSGpkRqw.webp" alt="" loading="lazy" decoding="async" width="1025" height="695" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI1IiBoZWlnaHQ9IjY5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*JbqxnPqZkNsZuqvSGpkRqw.png" /></p>

<p><a href="https://invest.firstrade.com/cgi-bin/main#/content/customerservice/promos/wirerebate/" target="_blank">Firstradeにログイン後、「カスタマーサービス」→「キャンペーン」→「送金手数料補助」を選択してください。</a></p>

<p><img src="/assets/e4d139fe0685/1*3UDeTN3dnh3fnM9HMdIurw.webp" alt="" loading="lazy" decoding="async" width="866" height="674" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjYiIGhlaWdodD0iNjc0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*3UDeTN3dnh3fnM9HMdIurw.png" /></p>

<p>送金情報を選択してください。</p>

<blockquote>
  <p><strong><em>もし送金情報が表示されない場合は、数日待ってから再度確認してください。（入金直後はすぐに表示されないことがあります）</em></strong></p>
</blockquote>

<p><img src="/assets/e4d139fe0685/1*U598Ew1kBCBC4fxCjLVv_w.webp" alt="" loading="lazy" decoding="async" width="872" height="918" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzIiIGhlaWdodD0iOTE4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*U598Ew1kBCBC4fxCjLVv_w.png" /></p>

<p><img src="/assets/e4d139fe0685/1*-KOs-E0FQ_Wy80GLl581OA.webp" alt="" loading="lazy" decoding="async" width="866" height="766" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjYiIGhlaWdodD0iNzY2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*-KOs-E0FQ_Wy80GLl581OA.png" /></p>

<p><strong>送金記録データの選択：</strong></p>

<ul>
  <li>
    <p>送金金融機関名： <code class="language-plaintext highlighter-rouge">LINE Bank Taiwan Limited</code></p>
  </li>
  <li>
    <p>金融機関が徴収する送金手数料：<code class="language-plaintext highlighter-rouge">25</code></p>
  </li>
</ul>

<p>「送信」→「確定」をクリックして申請を完了します。</p>

<p><img src="/assets/e4d139fe0685/1*RYYu26VBBJhxT76Ht1toMQ.webp" alt="" loading="lazy" decoding="async" width="691" height="388" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2OTEiIGhlaWdodD0iMzg4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*RYYu26VBBJhxT76Ht1toMQ.png" /></p>

<p>約2〜3営業日で送金補助金を受け取ることができます。</p>

<p><img src="/assets/e4d139fe0685/1*L-g13ZQ2uS2PqHRyomDD4g.webp" alt="" loading="lazy" decoding="async" width="976" height="124" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NzYiIGhlaWdodD0iMTI0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*L-g13ZQ2uS2PqHRyomDD4g.png" /></p>

<p>「マイアカウント」→「アカウント履歴」で送金手数料補助の記録を確認できます。</p>

<blockquote>
  <p><em>Firstradeに少し問題があり、約1日の空白期間があります：申請状況が消えたり、口座記録に補助金が反映されなかったりしますが、約1日後に入金記録が表示されます！</em></p>
</blockquote>

<blockquote>
  <p><strong><em>LINE Bankは私たちにTWD $150のみ請求しますが、実際の送金手数料はUSD $25を超えるため、USD $25を補助します。</em></strong></p>
</blockquote>

<h3 id="免責事項">免責事項</h3>

<p>本文は個人の操作共有のみであり、完全な正確性を保証するものではありません。ご利用は実際の状況を優先してください。著者は使用に伴う損失について一切責任を負いません。</p>

<h3 id="詐欺対策コーナー">詐欺対策コーナー</h3>

<h4 id="二段階認証">二段階認証</h4>

<p><img src="/assets/e4d139fe0685/1*jPfNxJGPBCY20do8y8Pz_g.webp" alt="" loading="lazy" decoding="async" width="1016" height="736" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDE2IiBoZWlnaHQ9IjczNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/e4d139fe0685/1*jPfNxJGPBCY20do8y8Pz_g.png" /></p>

<p>必ず「マイアカウント」→「設定」→「認証アプリ」を有効にしてください。</p>

<p>こうすることで、見知らぬデバイスでログインする際は必ず二段階認証を完了しなければなりません。</p>

<h4 id="メールとリンクのドメイン">メールとリンクのドメイン</h4>

<p><img src="/assets/e4d139fe0685/1*Rqr5E1ptXgjXh686EAr_UQ.webp" alt="" loading="lazy" decoding="async" width="922" height="646" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjIiIGhlaWdodD0iNjQ2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/e4d139fe0685/1*Rqr5E1ptXgjXh686EAr_UQ.png" /></p>

<p><img src="/assets/e4d139fe0685/1*R_zbtsoMNVK6ryeSjkMzIQ.webp" alt="" loading="lazy" decoding="async" width="564" height="56" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjQiIGhlaWdodD0iNTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/e4d139fe0685/1*R_zbtsoMNVK6ryeSjkMzIQ.png" /></p>

<p>メールの形式が本物と同じでも、送信者が <strong>firstrade.com</strong> かどうかを必ず確認し、メール内のリンクは絶対にクリックしないでください。<strong>どうしてもクリックする場合は、リンク先が firstrade.com であることを十分に確認してください。</strong></p>

<blockquote>
  <p><em>技術的に<strong>詐欺メールや偽サイトは全く同じものを作成可能で</strong>、真偽の判断が難しいです；URL部分：</em></p>
</blockquote>

<blockquote>
  <p><strong><em>firstrade.com以外はすべて詐欺です！詐欺です！詐欺です！</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>firstrade.com以外はすべて詐欺です！詐欺です！詐欺です！</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>firstrade.com以外はすべて詐欺です！詐欺です！詐欺です！</em></strong></p>
</blockquote>

<p><em><a href="https://medium.com/zrealm-life/%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E5%AD%B8-line-bank-%E5%85%A5%E9%87%91-firstrade-%E5%BF%AB%E9%80%9F%E5%88%B0%E5%B8%B3-%E6%89%8B%E7%BA%8C%E8%B2%BB%E5%8F%AA%E8%A6%81-150-%E5%85%83%E5%8F%8A%E5%B8%B3%E6%88%B6%E5%8D%87%E7%B4%9A-%E7%B4%84%E5%AE%9A%E8%BD%89%E5%B8%B3-%E6%89%8B%E7%BA%8C%E8%B2%BB%E8%A3%9C%E5%8A%A9%E7%94%B3%E8%AB%8B%E6%95%99%E5%AD%B8-e4d139fe0685" target="_blank">Post</a> Mediumから変換： <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>による。</em></p>]]></content>
  </entry><entry>
    <title type="html">釜山自由行｜VISIT BUSAN PASSで8日間の絶景＆グルメ満喫ガイド</title>
    <link href="https://jp.zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E9%87%9C%E5%B1%B1%E8%87%AA%E7%94%B1%E8%A1%8C-visit-busan-pass%E3%81%A78%E6%97%A5%E9%96%93%E3%81%AE%E7%B5%B6%E6%99%AF-%E3%82%B0%E3%83%AB%E3%83%A1%E6%BA%80%E5%96%AB%E3%82%AC%E3%82%A4%E3%83%89-8ace34a1a3d8/" rel="alternate" type="text/html" title="釜山自由行｜VISIT BUSAN PASSで8日間の絶景＆グルメ満喫ガイド" />
    <published>2025-08-13T12:38:54+08:00</published>
    <updated>2025-08-17T10:55:29+08:00</updated>
    <id>https://jp.zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/8ace34a1a3d8</id><summary type="html">釜山通行證で南北の観光スポットを効率的に巡りたい旅行者必見。交通費削減と人気グルメ体験を両立し、ストレスフリーな旅を実現します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="Z 度旅行遊記" /><category term="生活" /><category term="旅行" /><category term="釜山" /><category term="韓国" /><category term="旅行記" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/8ace34a1a3d8/1*06AC2xvA-jb4pjaIQg6fbQ.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E9%87%9C%E5%B1%B1%E8%87%AA%E7%94%B1%E8%A1%8C-visit-busan-pass%E3%81%A78%E6%97%A5%E9%96%93%E3%81%AE%E7%B5%B6%E6%99%AF-%E3%82%B0%E3%83%AB%E3%83%A1%E6%BA%80%E5%96%AB%E3%82%AC%E3%82%A4%E3%83%89-8ace34a1a3d8/"><![CDATA[<h3 id="旅行記-2025年-韓国釜山-8日間7泊の自由旅行">[旅行記] 2025年 韓国釜山 8日間7泊の自由旅行</h3>

<p>南から北へ、釜山通行証 VISIT BUSAN PASS を使って、美しい景色を楽しみ、美味しい食事を味わい、あなただけの釜山の旅を始めましょう。</p>

<p><img src="/assets/8ace34a1a3d8/1*06AC2xvA-jb4pjaIQg6fbQ.webp" alt="広安大橋" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*06AC2xvA-jb4pjaIQg6fbQ.jpeg" /></p>

<p>広安大橋</p>

<h4 id="背景">背景</h4>

<p>去年 <a href="/posts/z-度旅行記/九州自由行-釜山発博多入国の郵輪旅で由布院-大分-福岡を満喫-cb65fd5ab770/"><strong>2024年「九州再訪9日自由旅行、釜山→博多クルーズ入国」</strong></a> では、韓国釜山から入国し船で福岡へ向かいました。その時は釜山で朝の短い時間だけ滞在し、海東龍宮寺と海雲台をざっと見ただけでした。今年の7〜8月に仕事の合間ができたので、再び釜山へより深く探検しに行きました。今回は同じく暇なPinkoiの同僚Seanと一緒です。</p>

<p>日付：2025/07/29–08/05</p>

<h3 id="tldr">TL;DR</h3>

<p>韓国釜山は日本のような静けさや秩序はないが、気ままで人情味がある。</p>

<p><strong>必須訪れるスポット：</strong></p>

<ul>
  <li>
    <p>[北] <a href="https://www.kkday.com/zh-tw/product/152412-gijang-skyline-luge-ticket-busan-south-korea?cid=19365" target="_blank">Skyline Luge スライドカート</a></p>
  </li>
  <li>
    <p>[北] <a href="https://www.kkday.com/zh-tw/product/134684-yacht-holic-busan-yacht-public-tour-gwangan-ri-haeundae-south-korea" target="_blank">釜山ヨットツアー Y Holic</a></p>
  </li>
  <li>
    <p>[北] <a href="https://www.kkday.com/zh-tw/product/123012-haeundae-blueline-park-sky-capsule-beach-train-ticket?cid=19365" target="_blank">カプセル列車</a></p>
  </li>
  <li>
    <p>[北] <a href="https://www.kkday.com/zh-tw/product/12213-busan-spa-land-centum-city-ticket?cid=19365" target="_blank">汗蒸幕</a></p>
  </li>
  <li>
    <p>[北] 海東龍宮寺（ヘドンヨングンサ）</p>
  </li>
  <li>
    <p>[北] 新世界デパート</p>
  </li>
  <li>
    <p>[南] 影島大橋</p>
  </li>
</ul>

<p><strong>必食：</strong></p>

<ul>
  <li>
    <p>[北] <a href="https://naver.me/GEiuqenG" target="_blank">焼きうなぎ — PUNGCHEONMAN</a></p>
  </li>
  <li>
    <p>[北] <a href="https://naver.me/x9zcuKNm" target="_blank">塩パン — Jayeondo saltbread</a></p>
  </li>
  <li>
    <p>[南] <a href="https://naver.me/xHmnku7F" target="_blank">のど鍋ふた焼肉 — Moggumung 南浦店</a></p>
  </li>
  <li>
    <p>[南] <a href="https://naver.me/GEiuXPsf" target="_blank">Milgot</a> あんこクリームよもぎ餅</p>
  </li>
</ul>

<p><strong>必須：</strong></p>

<ul>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/138477-visit-busan-pass-discount-free-attractions?cid=19365" target="_blank"><strong>韓国釜山パス VISIT BUSAN PASS</strong></a> <strong>（必ず使うべき、とても節約できる）</strong></p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/138477-visit-busan-pass-discount-free-attractions?cid=19365" target="_blank"><strong>韓国釜山パス VISIT BUSAN PASS</strong></a> <strong>（必ず使うべき、とても節約できる）</strong></p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/138477-visit-busan-pass-discount-free-attractions?cid=19365" target="_blank"><strong>韓国釜山パス VISIT BUSAN PASS</strong></a> <strong>（必ず使うべき、とても節約できる）</strong></p>
  </li>
</ul>

<blockquote>
  <p><em>今回食べられなかったもの：海鮮チヂミ（逃した）、豚肉スープご飯（<a href="/posts/z-度旅行記/九州自由行-釜山発博多入国の郵輪旅で由布院-大分-福岡を満喫-cb65fd5ab770/">前回食べた</a>）、生タコ（生ものは食べない。Instagramで多くの人が食中毒になったのを見た）、醤油漬けカニ（生ものは食べない）</em></p>
</blockquote>

<h3 id="出発前の準備">出発前の準備</h3>

<h4 id="行">行</h4>

<h4 id="航空券">航空券</h4>

<p><img src="/assets/8ace34a1a3d8/1*UkWjvZsjTVT4z6IbvwBBFQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="634" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjYzNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*UkWjvZsjTVT4z6IbvwBBFQ.png" /></p>

<p>釜山航空 ( <strong>受託手荷物 15KG 含む</strong> )。</p>

<p>価格： <strong>NT$6,728 / 人</strong> 。</p>

<ul>
  <li>
    <p>出発：07/29（火）台北桃園（TPE）16:25 -&gt; 釜山金海（PUS）19:55</p>
  </li>
  <li>
    <p>帰路：08/05（火）釜山金海（PUS）10:50 -&gt; 台北桃園（TPE）12:35</p>
  </li>
</ul>

<p>総日数は8日間、実際の滞在は6日間（初日と最終日は基本的に飛行機の移動のみ）。</p>

<h4 id="交通カード">交通カード</h4>

<p><img src="/assets/8ace34a1a3d8/1*AnOi_kWaK4ET_udnUwB6nQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="702" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjcwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*AnOi_kWaK4ET_udnUwB6nQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*TwuSm6wAS-J7_s6nLrnKLg.webp" alt="KKday 実体交通カード" loading="lazy" decoding="async" width="554" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*TwuSm6wAS-J7_s6nLrnKLg.png" /></p>

<p><a href="https://www.kkday.com/zh-tw/product/18161-t-money-public-transit-card-pick-up-at-taiwan-taoyuan-international-airport-south-korea?cid=19365" target="_blank">KKday 実体交通カード</a></p>

<p>今年のiPhoneはAppleウォレットの交通カード内のTmoneyを直接使ってチャージでき、とても便利です。しかし、私はすでに<a href="https://www.kkday.com/zh-tw/product/18161-t-money-public-transit-card-pick-up-at-taiwan-taoyuan-international-airport-south-korea?cid=19365" target="_blank">去年購入した実物カードにチャージ済み</a>なので、使いませんでした。</p>

<p>また、今年からは <a href="https://wowpass.io/zh-TW" target="_blank">Wowpass App</a> を通じて交通カードに直接チャージが可能になりました。手順はまずクレジットカードでWowpassにチャージし、次にWowpassからTmoneyに入金する形で、手続きが多く手数料もかかります。</p>

<p><img src="/assets/8ace34a1a3d8/1*Sz8gh4I3s8sx5_0fsyT4oA.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Sz8gh4I3s8sx5_0fsyT4oA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*PzzH6uT3djtj-egP-1A3YA.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*PzzH6uT3djtj-egP-1A3YA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*C5s-bq9vOTiwDkIIbGHQig.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*C5s-bq9vOTiwDkIIbGHQig.jpeg" /></p>

<blockquote>
  <p>どのタイプでも、出発前に台湾でクレジットカードを使ってチャージすることをおすすめします（発行会社によっては対応していない場合があります）。または、韓国に持参した現金で機械でチャージする方法もあります。 <a href="https://map.naver.com/p/" target="_blank">Naver Map</a></p>
</blockquote>

<blockquote>
  <p><a href="https://map.naver.com/p/" target="_blank"><strong><em>韓国では必ずNaver Mapを使いましょう。</em></strong></a></p>
</blockquote>

<blockquote>
  <p><strong><em><a href="https://map.naver.com/p/" target="_blank">韓国では必ずNaver Mapを使うべき。</a></em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em><a href="https://map.naver.com/p/" target="_blank">韓国では必ずNaver Mapを使うべき。</a></em></strong></p>
</blockquote>

<h4 id="バスの規則">バスの規則</h4>

<p><img src="/assets/8ace34a1a3d8/1*SdjC7IxAtx08bLLFngwnzA.webp" alt="" loading="lazy" decoding="async" width="928" height="720" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjgiIGhlaWdodD0iNzIwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*SdjC7IxAtx08bLLFngwnzA.png" /></p>

<ul>
  <li>
    <p><strong>釜山のバス規則では、20インチ以上のスーツケースや手持ちのタンブラーの持ち込みは禁止されています（持っているだけで飲まなくても、必ず止められます）。</strong></p>
  </li>
  <li>
    <p>バスはすべて <strong>前のドアから乗車し、後ろのドアから降車</strong> します；前のドアのカードリーダーは通常運転席の後ろ側にあります。</p>
  </li>
  <li>
    <p><strong>また、店舗では外部からのゴミは受け付けていません。自分で氷入りのカップ飲料を持っている場合は、観光地や百貨店で飲み終えてから捨ててから移動することをおすすめします。そうしないと面倒です。</strong></p>
  </li>
  <li>
    <p>2人以上なら、タクシーを使い放題でもいいです。釜山のタクシーは多くて安く、しかも新しくて便利です。</p>
  </li>
  <li>
    <p>地下鉄は方向を確認してから乗車してください</p>
  </li>
</ul>

<h4 id="韓国釜山パス-visit-busan-pass"><a href="https://www.kkday.com/zh-tw/product/138477-visit-busan-pass-discount-free-attractions?cid=19365" target="_blank">韓国釜山パス VISIT BUSAN PASS</a></h4>

<p>Busan Passには、時間制限付き（24/48時間）無制限タイプと、使用回数制限タイプ（180日以内に使い切る）があります。</p>

<p><img src="/assets/8ace34a1a3d8/1*87TkvJQSQbrD1GcZsN3i7w.webp" alt="" loading="lazy" decoding="async" width="1252" height="1124" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjUyIiBoZWlnaHQ9IjExMjQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*87TkvJQSQbrD1GcZsN3i7w.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ujmSSMVX5IINmCmCknawlQ.webp" alt="KKday 2025/08 釜山パス情報" loading="lazy" decoding="async" width="1058" height="1240" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDU4IiBoZWlnaHQ9IjEyNDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*ujmSSMVX5IINmCmCknawlQ.png" /></p>

<p><a href="https://www.kkday.com/zh-tw/product/138477-visit-busan-pass-discount-free-attractions?cid=19365" target="_blank">KKday 2025/08 釜山パス情報</a></p>

<ul>
  <li>
    <p>日程が8日間に分かれていて、行きたい場所も限られていたため、<strong>BIG5を2枚購入しました。</strong></p>
  </li>
  <li>
    <p>価格： <strong>NT$1,380 *2枚 = NT$2,760</strong></p>
  </li>
  <li>
    <p>電子版は注文時のQRコードを直接提示してご利用ください。</p>
  </li>
</ul>

<p><strong>実際の使用状況は以下の通りです：</strong></p>

<p><img src="/assets/8ace34a1a3d8/1*ItIzgsZFoDEzwSLJK870Dw.webp" alt="" loading="lazy" decoding="async" width="1020" height="826" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDIwIiBoZWlnaHQ9IjgyNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ItIzgsZFoDEzwSLJK870Dw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*Q1L0AgRhDM9Eh2WiByj06w.webp" alt="KKday 2025/08 釜山 Pass 情報" loading="lazy" decoding="async" width="1000" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAwIiBoZWlnaHQ9IjEyMDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*Q1L0AgRhDM9Eh2WiByj06w.png" /></p>

<p><a href="https://www.kkday.com/zh-tw/product/138477-visit-busan-pass-discount-free-attractions?cid=19365" target="_blank">KKday 2025/08 釜山パス情報</a></p>

<ul>
  <li>
    <p>青色が一つ足りない（太宗台には行かなかった）</p>
  </li>
  <li>
    <p>海雲台海岸列車は2日間、それぞれ1回ずつ乗りました。</p>
  </li>
</ul>

<h4 id="釜山ヨットツアー-y-holic-予約️">釜山ヨットツアー Y Holic 予約⚠️</h4>

<p>釜山パスを使って釜山のヨットツアーに参加するには、事前に船主に予約が必要です。私たちはY Holicを選びましたが、この会社を例に説明します。</p>

<p><strong>パスを購入した後、以下の方法で船主にメッセージを送信してください：</strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>IG：@yachtholic_info（私たちはLineで連絡しています）
LINE：@yachtholic
Email：yh@yachtholic.com
WeChat：yachtholic
</code></pre></div></div>

<p>人数、日付、時間帯、Email または連絡先と釜山 Pass の QRコードをお知らせください。</p>

<p>確認待ち、問題なければ予約完了です！</p>

<ul>
  <li>
    <p>夜の部（18:00開始）は <strong>一人あたり別途5,000ウォンが必要</strong> で、現地で支払うか事前に振り込みが可能です。</p>
  </li>
  <li>
    <p><strong>身分確認のため、30分前に現地で並ぶ必要があります</strong></p>
  </li>
  <li>
    <p>私たちは約18:30に夕日を見ました</p>
  </li>
</ul>

<blockquote>
  <p><a href="https://www.kkday.com/zh-tw/product/134684-yacht-holic-busan-yacht-public-tour-gwangan-ri-haeundae-south-korea?cid=19365" target="_blank"><em>パスを購入しなくても、直接ヨットツアーの予約が可能です。</em></a></p>
</blockquote>

<h4 id="韓国釜山海雲台ブルーラインパーク海岸列車スカイカプセル列車チケット"><a href="https://www.kkday.com/zh-tw/product/123012-haeundae-blueline-park-sky-capsule-beach-train-ticket?cid=19365" target="_blank">韓国釜山｜海雲台ブルーラインパーク海岸列車・スカイカプセル列車チケット</a></h4>

<p>ご注意ください：<strong>海岸列車とカプセル列車は異なります</strong>。間違えて購入しないでください。美しいカプセル列車は釜山パスに含まれておらず、別途チケットを購入する必要があります。また、<strong>非常に人気があるため、出発前に必ず予約をしてください</strong>。</p>

<ul>
  <li>
    <p>スカイカプセル 尾浦出発</p>
  </li>
  <li>
    <p>2人用（1枚で2人利用）</p>
  </li>
  <li>
    <p><strong>価格：NT$861</strong></p>
  </li>
</ul>

<h4 id="韓国simカード韓国-高速無制限データ-esim"><a href="https://www.kkday.com/zh-tw/product/138273-korea-network-card-korea-express-esim-500mb-5gb-50gb-unlimited-plan-south-korea?cid=19365" target="_blank">韓国SIMカード｜韓国 高速無制限データ eSIM</a></h4>

<ul>
  <li>7日間無制限データプラン（最終日は朝に空港へ向かうため購入しませんでした）</li>
</ul>

<h4 id="naver-map"><a href="https://map.naver.com/p/" target="_blank">Naver Map</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*PrUwaqdQWWW0uvNzc6NnLQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="959" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk1OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*PrUwaqdQWWW0uvNzc6NnLQ.png" /></p>

<blockquote>
  <p><a href="https://map.naver.com/p/" target="_blank"><strong><em>韓国では必ずNaver Mapを使いましょう。</em></strong></a></p>
</blockquote>

<blockquote>
  <p><strong><em><a href="https://map.naver.com/p/" target="_blank">韓国では必ずNaver Mapを使うべき。</a></em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em><a href="https://map.naver.com/p/" target="_blank">韓国では必ずNaver Mapを使うべき。</a></em></strong></p>
</blockquote>

<p><strong>挿話 — 出発前日にNaver Mapにログインしようとしたらアカウントがロックされていた</strong></p>

<p><img src="/assets/8ace34a1a3d8/1*0SzoLbnn_g-Nu1Gx0aYF9Q.webp" alt="" loading="lazy" decoding="async" width="456" height="616" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NTYiIGhlaWdodD0iNjE2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*0SzoLbnn_g-Nu1Gx0aYF9Q.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*vjnO23ajw0h8XUZ5LBhryw.webp" alt="&lt;https://help.naver.com/service/5640/contents/20783?lang=en&amp;osType=COMMONOS&gt;" loading="lazy" decoding="async" width="440" height="616" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NDAiIGhlaWdodD0iNjE2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*vjnO23ajw0h8XUZ5LBhryw.png" /></p>

<p><a href="https://help.naver.com/service/5640/contents/20783?lang=en&amp;osType=COMMONOS" target="_blank">https://help.naver.com/service/5640/contents/20783?lang=en&amp;osType=COMMONOS</a></p>

<p><strong>原因は台湾でのログインが疑わしい活動と見なされ、Naverアカウントの保護機能が作動したためと思われます。</strong></p>

<p>本人認証を通じてアカウントを再有効化できますが、名前の入力ミスか外国人は実名認証が通らないのか不明で、どんなに入力しても情報エラーが表示され、最終的にアカウントがロックされてしまいました。</p>

<p>ネットの情報を調べると、保護機能解除の申請フォーム「<a href="https://help.naver.com/inquiry/input.help?categoryNo=18202&amp;serviceNo=5640&amp;lang=en" target="_blank">Members residing outside of Korea_Request to lift account protection measures</a>」があると書かれていますが、名前の問題があり、初回の申請は却下されました：</p>

<p><img src="/assets/8ace34a1a3d8/1*lc5k61s4A4CBsVQ7ZYBOKg.webp" alt="申訴失敗" loading="lazy" decoding="async" width="1101" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTAxIiBoZWlnaHQ9IjEyMDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*lc5k61s4A4CBsVQ7ZYBOKg.png" /></p>

<p>申し立て失敗</p>

<p>2通目は<a href="https://help.naver.com/inquiry/input.help?categoryNo=14955&amp;serviceNo=5640&amp;lang=ko" target="_blank">直接Help Centerへ</a>申請フォームを記入しました：</p>

<p><img src="/assets/8ace34a1a3d8/1*Mn_YZfHr9U8tXKYCjySHVg.webp" alt="" loading="lazy" decoding="async" width="1200" height="1071" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwNzEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*Mn_YZfHr9U8tXKYCjySHVg.png" /></p>

<p>申立内容を入力しました：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. あなたのNAVER ID。  
NAVERのアカウントを忘れた場合は、メールや携帯電話でアカウントを探すことができます。

2. 登録された名前、生年月日、連絡先情報（携帯番号またはメールアドレス）。  
生年月日：YYYY/MM/DD 登録時に入力した誕生日  
携帯番号：+886XXXXXXXXX 登録時に入力した携帯番号  
メール：登録時に入力したメールアドレス  
登録名：申し訳ありませんが、入力した名前を忘れてしまいました。以下のいずれかかもしれません：  
XXXXX LI  
LI XXXXX  
XXX  
李XX  
ただし、本当の名前は名字がLiで、名前はXXXXです。

3. 海外の身分証明書を添付してください。  
添付ファイルをご参照ください。

4. NAVERヘルプセンターへの要望内容。  
入力した名前を忘れてしまい、アカウント保護措置の解除を希望します。
</code></pre></div></div>

<p>提供できる情報はできるだけ多く、最後にパスポートの個人情報ページの画像を添付してください。</p>

<p><strong>そして無事に解除できました：</strong></p>

<p><img src="/assets/8ace34a1a3d8/1*uvUo0CgFkqTfuOp87UtahQ.webp" alt="" loading="lazy" decoding="async" width="1038" height="1122" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDM4IiBoZWlnaHQ9IjExMjIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*uvUo0CgFkqTfuOp87UtahQ.png" /></p>

<p>臨時パスワードのメールが届くので、そのパスワードでNaver Mapにログインしてください。<strong>ログイン後は必ずパスワードを変更し、二段階認証を設定してください（Naverのログイン保護機能は解除しています）。</strong></p>

<blockquote>
  <p><em>Naverの返信は非常に早く、半日以内に問題が解決しました。突然アカウントがロックされるのを心配する場合は、事前に「<a href="https://help.naver.com/inquiry/input.help?categoryNo=18202&amp;serviceNo=5640&amp;lang=en" target="_blank">韓国外居住者向け_アカウント保護解除申請</a>」を申請することをおすすめします。(</em> <a href="https://www.dcard.tw/f/korea_study/p/257877877" target="*blank">こちらの記入例も参考に</a> _).*</p>
</blockquote>

<h4 id="食事">食事</h4>

<p>事前予約したのは、西面の韓牛焼肉【花肉店 田浦店】のみです。<a href="https://www.catchtable.net/zh-TW/shop/busan_kosaljip?operationType=REMOTE_WAITING_GLOBAL" target="_blank">花肉店 田浦店</a> 。</p>

<p><img src="/assets/8ace34a1a3d8/1*oXyIDJJvynQfqfD_-Yb8cw.webp" alt="CatchTable" loading="lazy" decoding="async" width="998" height="1198" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5OTgiIGhlaWdodD0iMTE5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*oXyIDJJvynQfqfD_-Yb8cw.png" /></p>

<p>CatchTable</p>

<p>というのも、<a href="https://www.catchtable.net/zh-TW/" target="_blank">Catchtable</a> というプラットフォームはかなり便利で、韓国のグルメレストランを事前に予約できます。</p>

<h4 id="楽しい">楽しい</h4>

<ul>
  <li>
    <p>Day 1 07/29（火）：釜山到着、直接海雲台ホテルへ</p>
  </li>
  <li>
    <p>Day 2 07/30 (水)：午前はSkyline Lugeスライドカートと海東龍宮寺、午後は海岸列車＋カプセル列車、海雲台へ戻り、釜山 BUSAN X the SKY、夜は味贊王焼肉</p>
  </li>
  <li>
    <p>Day 3 07/31（木）：午前 青沙浦、ハニーバタートースト、海岸列車で海雲台へ、午後 スパランド、夜 釜山ヨットツアー、夜 焼きウナギ</p>
  </li>
  <li>
    <p>Day 4 08/01 (金)：南浦洞へ移動、松島海上ケーブルカー、龍宮雲橋、甘川洞文化村、夜は喉鍋蓋焼肉、釜山タワーで夜景鑑賞</p>
  </li>
  <li>
    <p>Day 5 08/02（土）：ロッテ百貨店、影島大橋開通（毎週土曜日のみ）</p>
  </li>
  <li>
    <p>Day 6 08/03（日）：ロッテ百貨店、プピョン缶詰市場、ペクチョン湾文化村、ポクチョンサ寺夜景</p>
  </li>
  <li>
    <p>Day 7 08/04 (月)：西面へ移動、夜は韓牛を食べる</p>
  </li>
  <li>
    <p>Day 8 08/05 (火)：釜山金海国際空港、帰路</p>
  </li>
</ul>

<h4 id="宿泊">宿泊</h4>

<h4 id="海雲台高麗良宵ホテル-day-1--day-4-3泊-"><a href="https://www.booking.com/hotel/kr/benikea-haeundae.zh-tw.html?label=gen173nr-10CAEoggI46AdIM1gEaOcBiAEBmAEzuAEHyAEM2AED6AEB-AEBiAIBqAIBuAKWo-bEBsACAdICJGZjZWEwODk4LTZkNzAtNGY0MS04OGViLTE1ZmUxZmJkOGQwZtgCAeACAQ&amp;sid=594a3964e5a18310cf9a473a9d09eb36&amp;aid=304142" target="_blank">海雲台高麗良宵ホテル (Day 1 — Day 4 3泊)</a> )</h4>

<p><img src="/assets/8ace34a1a3d8/1*f5NuKjYVcPd6G78lEtIncQ.webp" alt="" loading="lazy" decoding="async" width="1090" height="872" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDkwIiBoZWlnaHQ9Ijg3MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*f5NuKjYVcPd6G78lEtIncQ.png" /></p>

<p>場所は比較的便利で、海雲台大通りまで徒歩約10分です。窓はありますが海の景色はなく、ツインルームです。</p>

<ul>
  <li><strong>価格：実際の支払いはNT$12,032で、1泊1人あたり約NT$2,000です。</strong></li>
</ul>

<h4 id="hotel-noah-4日目7日目の3泊"><a href="https://www.agoda.com/zh-cn/hotel-noah_3/hotel/busan-kr.html" target="_blank">Hotel Noah (4日目〜7日目の3泊)</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*UgPFi5UgawBzJbgluC5Vdw.webp" alt="" loading="lazy" decoding="async" width="1100" height="652" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTAwIiBoZWlnaHQ9IjY1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*UgPFi5UgawBzJbgluC5Vdw.png" /></p>

<p>地下鉄札嘎其駅から徒歩約5分、向かい側がBIFF広場で、窓付きのツインルームです。</p>

<ul>
  <li><strong>価格：実際の支払いはNT$7,783で、1泊1人あたり約NT$1,298です。</strong></li>
</ul>

<h4 id="air-sky-hotel-7日目8日目-1泊"><a href="https://www.booking.com/hotel/kr/eeoseukaigwangwanghotel.zh-tw.html" target="_blank">Air Sky Hotel (7日目〜8日目 1泊)</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*mosy-Q7nQzyOIfPmAi3twQ.webp" alt="" loading="lazy" decoding="async" width="1124" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*mosy-Q7nQzyOIfPmAi3twQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*26rsk_MCYmlbNhmKiTKqKw.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*26rsk_MCYmlbNhmKiTKqKw.jpeg" /></p>

<p>空港からわずか一駅で、待ち時間＋乗車時間＋徒歩合わせて約10分で空港に到着します。窓付きのツインルームです。</p>

<ul>
  <li><strong>価格：実際の支払い NT$2,835、1泊1人あたり約 NT$1,418。</strong></li>
</ul>

<blockquote>
  <p><em>余談：このホテルは予約完了後に定型文メッセージでデポジットの支払いを求めてきますが、すでに全額カード決済済みの場合は無視して問題ありません。</em></p>
</blockquote>

<h4 id="ビザ">ビザ</h4>

<p>韓国はビザ免除で、出発の3日前までに<a href="https://www.e-arrivalcard.go.kr/portal/apply/agreementPolicy.do?applyType=P" target="_blank">オンラインで入国申請書を記入</a>すれば、到着後パスポートだけで入国手続きが完了します。</p>

<blockquote>
  <p>準備完了、出発！</p>
</blockquote>

<h3 id="day-1-0729-火-台湾から海雲台へ">Day 1 07/29 (火) 台湾から海雲台へ</h3>

<h4 id="1330-桃園国際空港第2ターミナル到着">~=13:30 桃園国際空港第2ターミナル到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*V9fB_UU_9T-t0Z4QN1WE4g.webp" alt="" loading="lazy" decoding="async" width="1200" height="807" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*V9fB_UU_9T-t0Z4QN1WE4g.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ZQfPfUI56V4EI_U2vgPj5A.webp" alt="" loading="lazy" decoding="async" width="964" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ZQfPfUI56V4EI_U2vgPj5A.png" /></p>

<p>大体13:50にカウンターでチェックイン開始、約14:10にチェックインと荷物預けが完了。</p>

<blockquote>
  <p><em>釜山航空の公式サイトで<a href="https://mtw.airbusan.com/mw/checkin/checkinList" target="_blank">オンラインチェックイン＋座席指定（無料）</a>が事前にできます。</em></p>
</blockquote>

<h4 id="1430-出国手続き完了食事">14:30 出国手続き完了＋食事</h4>

<p><img src="/assets/8ace34a1a3d8/1*QzSioHsBFjr_LBpX2NlgWw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*QzSioHsBFjr_LBpX2NlgWw.jpeg" /></p>

<p>釜山に到着してすぐホテルに向かうため、台湾でしっかり食事を済ませました。</p>

<h4 id="1500-搭乗待ち開始esimを有効化">15:00 搭乗待ち開始、eSIMを有効化</h4>

<p><img src="/assets/8ace34a1a3d8/1*AXE6WNQdcgDXCFuGn7k5PA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*AXE6WNQdcgDXCFuGn7k5PA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ZdqpL-V_F7GA8qsTKEa93g.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ZdqpL-V_F7GA8qsTKEa93g.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*QbB73S1hJj3Buwzqf8wdSw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*QbB73S1hJj3Buwzqf8wdSw.jpeg" /></p>

<p>空港のネットワークが不安だったので、先に<a href="https://zhgchg.li/posts/aacd5f5cacd1/#%E4%BA%8B%E5%85%88%E5%95%9F%E7%94%A8-esim-iphone-%E7%82%BA%E4%BE%8B" target="_blank">台湾でeSIMを有効化</a>しました。</p>

<h4 id="1640-飛行機離陸">~=16:40 飛行機離陸</h4>

<p><img src="/assets/8ace34a1a3d8/1*TnEN0BSfol902HADb8_rNw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*TnEN0BSfol902HADb8_rNw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*_2jmZ8VV-D_8uI43mnnLHQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*_2jmZ8VV-D_8uI43mnnLHQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*mKI4jAmJiEQdoyY8E1VU8g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*mKI4jAmJiEQdoyY8E1VU8g.jpeg" /></p>

<p>15分遅れて出発しました。座席はかなり狭かったです。</p>

<h4 id="2005-韓国釜山に到着">~=20:05 韓国釜山に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*GmQ4yzkxgxt9MJgcXwwauA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*GmQ4yzkxgxt9MJgcXwwauA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ZmBqlt5oYtJRpCHdqD1W1g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ZmBqlt5oYtJRpCHdqD1W1g.jpeg" /></p>

<blockquote>
  <p><em>釜山空港は軍民共用空港で、撮影は禁止されています。</em></p>
</blockquote>

<h4 id="2030-荷物受け取り入国手続き完了">~=20:30 荷物受け取り＋入国手続き完了</h4>

<p><img src="/assets/8ace34a1a3d8/1*6TN-R2eaqfuh_m2cddvJRA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*6TN-R2eaqfuh_m2cddvJRA.jpeg" /></p>

<p>まず空港のコンビニで軽食を買ってエネルギー補給をし、両替と少し休憩をしました。</p>

<h4 id="2100-金海軽電鉄-到着--空港駅">~=21:00 金海軽電鉄 到着 — 空港駅</h4>

<p>空港から出て徒歩約5分で到着します。</p>

<p><img src="/assets/8ace34a1a3d8/1*9qFJw2RhaG6aaQae1WHrPA.webp" alt="" loading="lazy" decoding="async" width="1204" height="1470" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjA0IiBoZWlnaHQ9IjE0NzAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*9qFJw2RhaG6aaQae1WHrPA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*qovf8TmzIHYe6jOPqAyqAw.webp" alt="" loading="lazy" decoding="async" width="990" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5OTAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*qovf8TmzIHYe6jOPqAyqAw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*S4Gkbfsb_0uApwcUSEiTnA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*S4Gkbfsb_0uApwcUSEiTnA.jpeg" /></p>

<p>まずSeanの交通カードにチャージします。ここには交通カードをチャージできる機械が2台あります（Self Service Charger）。<strong>チャージは韓国ウォン1000ウォン単位でしかできません</strong>。</p>

<p><img src="/assets/8ace34a1a3d8/1*o-mrmvVu8YonD9G7kFgn0A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*o-mrmvVu8YonD9G7kFgn0A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*5PANgTxqra2B7_S1knjfkA.webp" alt="" loading="lazy" decoding="async" width="1200" height="1023" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwMjMiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*5PANgTxqra2B7_S1knjfkA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*jILCIPwHH4B2sUCZb5glEg.webp" alt="" loading="lazy" decoding="async" width="742" height="1382" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NDIiIGhlaWdodD0iMTM4MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*jILCIPwHH4B2sUCZb5glEg.png" /></p>

<p>改札を通ったら、沙上駅（Sasang Station）行きのホームを探してください。次の駅は「西釜山流通地区」です。</p>

<h4 id="2115-沙上駅に到着し緑線に乗り換え">~=21:15 沙上駅に到着し、緑線に乗り換え</h4>

<p><img src="/assets/8ace34a1a3d8/1*54uF-nAbXp068jDEvOSRxQ.webp" alt="" loading="lazy" decoding="async" width="732" height="1592" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MzIiIGhlaWdodD0iMTU5MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*54uF-nAbXp068jDEvOSRxQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*SU68g_MSrPTZeJQ7BFQLhg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*SU68g_MSrPTZeJQ7BFQLhg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*WR7xmcLqxByn81lIAdRl6g.webp" alt="" loading="lazy" decoding="async" width="676" height="1572" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NzYiIGhlaWdodD0iMTU3MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*WR7xmcLqxByn81lIAdRl6g.png" /></p>

<p>ここでは地面の緑色の案内に沿って進むだけで、軽軌の駅から地下鉄の緑線に乗り換えられます。「<strong>長山</strong>」方面（もう一方は<strong>梁山</strong>方面で、字を間違えないように注意）へ向かい、次の駅は「甘田」です。</p>

<h4 id="2120-緑線沙上駅に到着しバスを待つ">~=21:20 緑線沙上駅に到着し、バスを待つ</h4>

<p><img src="/assets/8ace34a1a3d8/1*mhSqB1__ButsItcOkBuTBw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*mhSqB1__ButsItcOkBuTBw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*rpFYA13Lb9nyNy1dAp50PA.webp" alt="" loading="lazy" decoding="async" width="1200" height="501" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjUwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*rpFYA13Lb9nyNy1dAp50PA.png" /></p>

<h4 id="2220-海雲台に到着">~=22:20 海雲台に到着</h4>

<p>海雲台駅に近づくと、地下鉄のアナウンスでカモメの鳴き声が流れます。</p>

<p><img src="/assets/8ace34a1a3d8/1*FCNMmVBqS2AKfNQjh5cVmg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*FCNMmVBqS2AKfNQjh5cVmg.jpeg" /></p>

<h4 id="2230-ホテル到着">~=22:30 ホテル到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*LOXnjLsRW91_eVYck5kGeQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*LOXnjLsRW91_eVYck5kGeQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*30mP_dahFonL0ve1n_vEig.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*30mP_dahFonL0ve1n_vEig.jpeg" /></p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/YbU4uG3pLjI" title="海雲台高麗良宵酒店" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<h4 id="2250-出門海雲台大街覓食">~=22:50 出門海雲台大街覓食</h4>

<p><img src="/assets/8ace34a1a3d8/1*yKUlVFqVaS2D6M7j16mfoQ.webp" alt="" loading="lazy" decoding="async" width="971" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NzEiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*yKUlVFqVaS2D6M7j16mfoQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*64lyMg61i9rRbmJcwxjjgQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*64lyMg61i9rRbmJcwxjjgQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*HjfYqKBHDe5_c0iF7QaHuw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*HjfYqKBHDe5_c0iF7QaHuw.jpeg" /></p>

<p>宿泊場所へ行く途中、海雲台伝統市場を通ります。ここでは多くの食べ物が売られています。</p>

<h4 id="2330-ホテルに戻って食事開始">~=23:30 ホテルに戻って食事開始</h4>

<p><img src="/assets/8ace34a1a3d8/1*vQBulLYRFkoUQC_Os4hPFw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*vQBulLYRFkoUQC_Os4hPFw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*SyBfYDcG8uh5ArLioXV9vg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*SyBfYDcG8uh5ArLioXV9vg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*My3vIyTLBNbTSDtfh4FtkA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*My3vIyTLBNbTSDtfh4FtkA.jpeg" /></p>

<p>最後にBBQフライドチキンの2種類の味と伝統市場の辛いトッポッキ、コンビニの酒を買いました。</p>

<blockquote>
  <p><em>フライドチキンは一人分で二人には十分で、二人分は多すぎる（台湾の四人分くらいの量に感じた）、合計でNT $1,210を支払った。</em></p>
</blockquote>

<blockquote>
  <p><em>このマンゴー酒（</em>マンゴーキューブ入りアイスティーハイボール<em>）は美味しいです（5％）。中にはマンゴーの缶詰果肉が入っていて、後で台湾のファミリーマートでも販売されていることがわかりました。</em></p>
</blockquote>

<h3 id="day-2-0730-水-skyline-luge-スライドカート海東竜宮寺海岸列車カプセル列車釜山-busan-x-the-sky味贊王焼肉">Day 2 07/30 (水) Skyline Luge スライドカート、海東竜宮寺、海岸列車、カプセル列車、釜山 BUSAN X the SKY、味贊王焼肉</h3>

<h4 id="0930-出発--とても良い天気">09:30 出発 — とても良い天気</h4>

<p><img src="/assets/8ace34a1a3d8/1*zShkz0mzeWJhZKml3P1D2A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*zShkz0mzeWJhZKml3P1D2A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*Yf9ZxEjhX1K-YMwhTaDgFw.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Yf9ZxEjhX1K-YMwhTaDgFw.jpeg" /></p>

<p>ホテルの入口にバス停があり、Skyline Lugeへ直通しています。</p>

<h4 id="1025-スカイラインルージュ-">10:25 スカイラインルージュ 👍👍👍</h4>

<p><img src="/assets/8ace34a1a3d8/1*Yv8wNXoEqXLZZJII4DQsxg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Yv8wNXoEqXLZZJII4DQsxg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*QXuBBjbiGpENtziQS-sagg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*QXuBBjbiGpENtziQS-sagg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*s71ofWNtvFfoIBqnf-0VJw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*s71ofWNtvFfoIBqnf-0VJw.jpeg" /></p>

<p>大体10:30頃にチケット交換の列に並び始めました（釜山Passは交換後に使用可能です）。人がかなり多く、約20分並んでチケットを受け取りました。釜山Passでは、スカイラインルージュを2回遊ぶか、1回のスカイラインルージュと1回のジップラインを選べますが、ほとんどの人はスカイラインルージュを2回選んでいました。</p>

<blockquote>
  <p><a href="https://www.kkday.com/zh-tw/product/152412-gijang-skyline-luge-ticket-busan-south-korea?cid=19365" target="*blank"><em>Passを購入していなくても、KKdayで先にチケットを買えます。</em></a> _<strong>（現地購入より安いですが、引き換えが必要です）</strong>*</p>
</blockquote>

<p><img src="/assets/8ace34a1a3d8/1*cLgWZh4YrAkhLDfIkUICpw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*cLgWZh4YrAkhLDfIkUICpw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*_V9oQVANR9ncErO9tWEsCw.webp" alt="" loading="lazy" decoding="async" width="978" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NzgiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*_V9oQVANR9ncErO9tWEsCw.png" /></p>

<p>チケットを交換したら、すぐ隣で自分のサイズに合ったヘルメットを選び、ヘルメットをかぶってからケーブルカーに乗ります。</p>

<h4 id="1100-ケーブルカーに乗る">~=11:00 ケーブルカーに乗る</h4>

<p><img src="/assets/8ace34a1a3d8/1*PT-mGar4So6od4dD3A6F5g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*PT-mGar4So6od4dD3A6F5g.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*YzED-cEVaw7wrylcSUjuKw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*YzED-cEVaw7wrylcSUjuKw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*YHu8QYJ2Cx1grupJ55ZmsQ.webp" alt="" loading="lazy" decoding="async" width="703" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*YHu8QYJ2Cx1grupJ55ZmsQ.png" /></p>

<p>人は皆駅のチケット交換や購入カウンターに集中しており、その後のロープウェイやルージュはほとんど並ばずに乗れます。ロープウェイの途中で下のコースが見え、約5分で出発地点に到着します。</p>

<p><img src="/assets/8ace34a1a3d8/1*doGVKHy5yunEpR7OFaa6rw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*doGVKHy5yunEpR7OFaa6rw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*f0KgbnLu921Hiq7QAZg5HQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*f0KgbnLu921Hiq7QAZg5HQ.jpeg" /></p>

<p>もしオープン式のロープウェイが苦手なら、今回行ったときに隣にもう一つの箱型ロープウェイがあり、もうすぐ開通しそうな感じでした（？）。</p>

<h4 id="1105-出発準備">11:05 出発準備</h4>

<p><img src="/assets/8ace34a1a3d8/1*QmbycT8d2Gh5wimLP18CPQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*QmbycT8d2Gh5wimLP18CPQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*SA-bWwl8EuFsllB6_O5IrA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*SA-bWwl8EuFsllB6_O5IrA.jpeg" /></p>

<p>上から隣のロッテワールドが見えます。</p>

<p>初めて乗車・入場する際は、手にスタンプを押され、スタッフによる簡単な説明があります。</p>

<p><img src="/assets/8ace34a1a3d8/1*UCPhQh3lnSwMiO9UBqoHDQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*UCPhQh3lnSwMiO9UBqoHDQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*loe9DLrp_dtUFnpYrwxAOw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*loe9DLrp_dtUFnpYrwxAOw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*i9BnnhpabwgnxuBDw_7dbA.webp" alt="" loading="lazy" decoding="async" width="917" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTciIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*i9BnnhpabwgnxuBDw_7dbA.png" /></p>

<p>操作方法はとにかく以下の通りです：</p>

<ul>
  <li>
    <p><strong>足をまっすぐにする</strong></p>
  </li>
  <li>
    <p><strong>後ろに進み、前にブレーキをかける</strong></p>
  </li>
  <li>
    <p>途中で止まってはいけません、途中で止まってはいけません、途中で止まってはいけません。完全に止まると、滑り続けるのが非常に難しくなります。</p>
  </li>
  <li>
    <p>適切に曲がる前に減速しないと、転倒します。</p>
  </li>
  <li>
    <p>追い越しに注意</p>
  </li>
  <li>
    <p><strong>両手で操作し、携帯電話を手に持ってはいけません。途中でカメラが写真を撮る機会があり、記念品店で購入できます。</strong></p>
  </li>
  <li>
    <p>個人の持ち物を落とさないように注意してください。</p>
  </li>
</ul>

<p><img src="/assets/8ace34a1a3d8/1*GGsBBz5201M0fOrH4T1sqQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="862" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*GGsBBz5201M0fOrH4T1sqQ.png" /></p>

<p>上から下へスクロールするのに約6分しかかかりません。</p>

<p>以下はお土産センターと途中で撮った写真が購入できる場所です。</p>

<p><img src="/assets/8ace34a1a3d8/1*17zdVTPo_LP48TizhwValw.webp" alt="" loading="lazy" decoding="async" width="941" height="1185" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDEiIGhlaWdodD0iMTE4NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*17zdVTPo_LP48TizhwValw.png" /></p>

<p>お土産センターを通り抜けて入口に戻り、もう一度ケーブルカーに並びました。</p>

<p><img src="/assets/8ace34a1a3d8/1*I0y7aZ0bpynBInkP18lcUQ.webp" alt="" loading="lazy" decoding="async" width="694" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2OTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*I0y7aZ0bpynBInkP18lcUQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*2Y0iQTWf9pE0fAZJEK7JDg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*2Y0iQTWf9pE0fAZJEK7JDg.jpeg" /></p>

<p>今回は再入場ゲート（スタッフの説明なしで直接遊べます）。</p>

<p><img src="/assets/8ace34a1a3d8/1*1aOU7IAPVNd6bSLNTaXRsw.webp" alt="" loading="lazy" decoding="async" width="1200" height="865" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*1aOU7IAPVNd6bSLNTaXRsw.png" /></p>

<p>申し訳ありませんが、「ㄏ勝。」の意味が不明です。もう少し詳しく教えていただけますか？</p>

<h4 id="1145-出発海東龍宮寺へ向かう">11:45 出発、海東龍宮寺へ向かう</h4>

<p>Skyline Lugeを出て向かい側にまっすぐ進むと海東龍宮寺があります。徒歩約10分、坂道です。</p>

<p><img src="/assets/8ace34a1a3d8/1*W8pHXqKZ-gEPUqqLQV7cSA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*W8pHXqKZ-gEPUqqLQV7cSA.jpeg" /></p>

<h4 id="1155-海東龍宮寺-ヘドンヨングンサ">11:55 海東龍宮寺 (ヘドンヨングンサ)</h4>

<p><a href="/posts/z-度旅行記/九州自由行-釜山発博多入国の郵輪旅で由布院-大分-福岡を満喫-cb65fd5ab770/"><strong>昨年も来ましたので</strong></a>、今回はざっと見て回るだけです。</p>

<p><img src="/assets/8ace34a1a3d8/1*QO6ie1PN4o8liIjIs2Y0qQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="861" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*QO6ie1PN4o8liIjIs2Y0qQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*5RNxsL0nD0TQ3I_UvwZQPg.webp" alt="" loading="lazy" decoding="async" width="947" height="1216" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDciIGhlaWdodD0iMTIxNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*5RNxsL0nD0TQ3I_UvwZQPg.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*NllO9Hy73kJQzWNGoW0ABA.webp" alt="" loading="lazy" decoding="async" width="917" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTciIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*NllO9Hy73kJQzWNGoW0ABA.png" /></p>

<p>大体11:55に海東龍宮寺の屋台入口に到着しました。</p>

<p><img src="/assets/8ace34a1a3d8/1*m-tact5LRxGmwTBeDj7D2w.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*m-tact5LRxGmwTBeDj7D2w.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*K2ByL3USjy1fUlipsZLv1g.webp" alt="" loading="lazy" decoding="async" width="1400" height="984" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*K2ByL3USjy1fUlipsZLv1g.png" /></p>

<p>今回初めて海東龍宮寺の扁額入口の右側からも入れることに気づきました。こちらは緩やかな下り坂で本殿に直接行けます。扁額入口の方は急な階段で歩きにくいです。</p>

<p><img src="/assets/8ace34a1a3d8/1*dyci1YPm-ApaeV2MDLsW2Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*dyci1YPm-ApaeV2MDLsW2Q.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*wpe6ymEfLMASAEivSVyyJQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*wpe6ymEfLMASAEivSVyyJQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*AvKx5_BLU1cAJSkrvY8u7A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*AvKx5_BLU1cAJSkrvY8u7A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*8RX8RXzZJ_4mW8hxss7hTw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*8RX8RXzZJ_4mW8hxss7hTw.jpeg" /></p>

<h4 id="1245-バスを待って松亭駅へ行く">12:45 バスを待って松亭駅へ行く</h4>

<p><img src="/assets/8ace34a1a3d8/1*hnGZPnjF3eIAeAp7nu-Seg.webp" alt="" loading="lazy" decoding="async" width="942" height="1196" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDIiIGhlaWdodD0iMTE5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*hnGZPnjF3eIAeAp7nu-Seg.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*05IR75W3B-T4g2QkInLjHg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*05IR75W3B-T4g2QkInLjHg.jpeg" /></p>

<p>釜山の暑さ対策はかなりしっかりしていて、信号待ちの場所には日傘があり、バス停にはほとんど扇風機が設置されていて、ボタンを押すと動きます。</p>

<h4 id="ルート計画は以下の図の通りです">ルート計画は以下の図の通りです：</h4>

<p><img src="/assets/8ace34a1a3d8/1*wbyHE15DgoW3_pkit_OR_A.webp" alt="" loading="lazy" decoding="async" width="1400" height="947" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk0NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*wbyHE15DgoW3_pkit_OR_A.png" /></p>

<p>Skyline Lugeからバスと徒歩で海岸列車の松亭駅へ行き、海岸列車で青沙浦駅まで乗り、カプセル列車に乗り換えて海雲台に戻ります。</p>

<h4 id="1315-松亭駅に到着">~=13:15 松亭駅に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*1W63YJR27-niR0rPFiNkdw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*1W63YJR27-niR0rPFiNkdw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*qKTgaE6w7QYNnHU41kgdRg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*qKTgaE6w7QYNnHU41kgdRg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*E1rZoLfWgHKUxb3qRAXhkg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*E1rZoLfWgHKUxb3qRAXhkg.jpeg" /></p>

<p>バス停から歩いて約10分かかり、とても暑くて日差しが強いです。</p>

<p><img src="/assets/8ace34a1a3d8/1*uQegRUm5OVql_OGz5L4TQg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*uQegRUm5OVql_OGz5L4TQg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*PvM5nguf_-Fv6NfoWztP-w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*PvM5nguf_-Fv6NfoWztP-w.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*J76MOVL-li-Tg6c__KNMKg.webp" alt="ref" loading="lazy" decoding="async" width="927" height="322" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjciIGhlaWdodD0iMzIyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*J76MOVL-li-Tg6c__KNMKg.png" /></p>

<p><a href="https://www.kkday.com/zh-tw/product/123012-haeundae-blueline-park-sky-capsule-beach-train-ticket?cid=19365" target="_blank">ref</a></p>

<p>13:30の便は満席だったので、14:00の便を予約しました。( <a href="http://m.site.naver.com/0URl8" target="_blank">時刻表</a> )</p>

<blockquote>
  <p><em>ちょっとしたエピソード：この駅の駅員は釜山パスのPDFファイルの提示を認めず、必ずKKdayアプリから証明書を開いて見せるよう指示されました。</em></p>
</blockquote>

<blockquote>
  <p><em>釜山パスで交換したチケットは当日のみ有効で、各駅で一度ずつ乗車できるため、途中で観光地に立ち寄ることが可能です。</em></p>
</blockquote>

<p><img src="/assets/8ace34a1a3d8/1*mCtniHyCFiDVmGqsr8fFfw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*mCtniHyCFiDVmGqsr8fFfw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*LBR8tx9HfigYr51-ih8dag.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*LBR8tx9HfigYr51-ih8dag.jpeg" /></p>

<p>まだ時間が早いので、まずコンビニで軽く腹ごしらえ。松亭駅を出るとすぐに松亭海水浴場があります（人が少なめな感じ）。ここにコンビニがあります。</p>

<h4 id="1340-待ち時間開始">~=13:40 待ち時間開始</h4>

<p>早めに並んで待つことを忘れないでください。そうしないと、一番後ろに立つことになります。</p>

<p><img src="/assets/8ace34a1a3d8/1*wMw1Bmz47wE2_ivQ4LtQAw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*wMw1Bmz47wE2_ivQ4LtQAw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*_jexN3EvstbOgkts27zQhg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*_jexN3EvstbOgkts27zQhg.jpeg" /></p>

<p>駅を出てプラットフォームまで歩き、プラットフォームで改札を通れば乗車待ちが始められます。</p>

<p>大体13:50にバスが到着し、人々が騒ぎながら列を作り始めます。</p>

<h4 id="1400-出発">~=14:00 出発</h4>

<p><img src="/assets/8ace34a1a3d8/1*HT17e69lak7tbTqoXCpVUg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*HT17e69lak7tbTqoXCpVUg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*QBfTvy19T_Jl6zvxVNDqfQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*QBfTvy19T_Jl6zvxVNDqfQ.jpeg" /></p>

<p>2列目の席に座ったら、景色がなかなか良かったです。</p>

<h4 id="1415-青沙浦に到着">~=14:15 青沙浦に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*xeOjrCl9pQx_u28XnJXELA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*xeOjrCl9pQx_u28XnJXELA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*6JA5jGLBfsMl2GJMmehhtw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*6JA5jGLBfsMl2GJMmehhtw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*H0sBRecqIdECSploIAYVpw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*H0sBRecqIdECSploIAYVpw.jpeg" /></p>

<p>降りてからホームで2階へ上がる階段を見ると、それがカプセル列車の乗り場です。</p>

<p><img src="/assets/8ace34a1a3d8/1*Y4jeQwk6jnpsbAklaKZI6g.webp" alt="" loading="lazy" decoding="async" width="945" height="1193" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDUiIGhlaWdodD0iMTE5MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Y4jeQwk6jnpsbAklaKZI6g.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*XDAIgiQb3qdEDSr546kNzg.webp" alt="" loading="lazy" decoding="async" width="572" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NzIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*XDAIgiQb3qdEDSr546kNzg.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*hrnYxziizbB6PrFv97Qiow.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*hrnYxziizbB6PrFv97Qiow.jpeg" /></p>

<p><a href="https://www.kkday.com/zh-tw/product/123012-haeundae-blueline-park-sky-capsule-beach-train-ticket?cid=19365" target="_blank">KKdayの注文証明書にあるリンク</a>を開くと、チケットの証明書が表示されます。2階に上がり、亭子のスタッフに証明書を見せると（私たちは14:30–15:00の時間帯を予約しました）、番号札を渡されます。時間になると番号を呼び始めますが、すでに呼び始めていた場合は呼び終わるまで待つしかありません。</p>

<p><img src="/assets/8ace34a1a3d8/1*KCbwTzka0L2cWDvX2O37iQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*KCbwTzka0L2cWDvX2O37iQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*FjPJSkqC67-UAhlwm9RRzA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*FjPJSkqC67-UAhlwm9RRzA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*5Tx02qf1e3U_IKWJaWjp8g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*5Tx02qf1e3U_IKWJaWjp8g.jpeg" /></p>

<p>待ち時間に隣の土産物店で扇子を買いました。</p>

<blockquote>
  <p><em>カプセル列車でも無料の扇子がもらえます（右端の写真）。</em></p>
</blockquote>

<h4 id="1430-カプセル列車の呼び出し待ち行列">~=14:30 カプセル列車の呼び出し待ち行列</h4>

<p>時間になるとスタッフが順番に番号を呼んで並ばせます。</p>

<p><img src="/assets/8ace34a1a3d8/1*ZPQgbN2k7kRG2KI-3YEfEA.webp" alt="" loading="lazy" decoding="async" width="934" height="1229" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzQiIGhlaWdodD0iMTIyOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ZPQgbN2k7kRG2KI-3YEfEA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*7S7dQYAf2Zqj_dxMjl_pDw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*7S7dQYAf2Zqj_dxMjl_pDw.jpeg" /></p>

<p>待機エリアの上には冷房があり、乗車前にチケットを確認します（事前に画面を準備しておくことを忘れずに）。乗車後、スタッフが集合写真を撮り、降車後に購入するかどうかを決めます。</p>

<h4 id="1440-カプセル列車-青沙浦---尾浦海雲台-出発">~=14:40 カプセル列車 青沙浦 -&gt; 尾浦(海雲台) 出発！👍👍👍</h4>

<p><img src="/assets/8ace34a1a3d8/1*fLpUWvXcdl3Ryc1ary_arQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*fLpUWvXcdl3Ryc1ary_arQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*nMQDysR6bNzOxVTLLU7rPQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*nMQDysR6bNzOxVTLLU7rPQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*l1JWUq3qAKEyDoyLJyzSPQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*l1JWUq3qAKEyDoyLJyzSPQ.jpeg" /></p>

<p>刺激的に見えますが、実際はゆっくり進みます。車内にはエアコンはありませんが、換気扇とスマホを接続して音楽を流せるスピーカーがあります。</p>

<p><img src="/assets/8ace34a1a3d8/1*w4zPWlwQcqHhF4WCokBVyQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*w4zPWlwQcqHhF4WCokBVyQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*L4f0Ebz-fi6SeW7ZZJeTRQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*L4f0Ebz-fi6SeW7ZZJeTRQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*67tHAjdjNoZLmHdg0bLZFw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*67tHAjdjNoZLmHdg0bLZFw.jpeg" /></p>

<p>景色を楽しみながらインスタ映え写真を撮る（？）</p>

<h4 id="1510-尾浦ヘウンデに到着">~=15:10 尾浦（ヘウンデ）に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*hTEuxliIs2s_098pdVaOsg.webp" alt="" loading="lazy" decoding="async" width="944" height="1203" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDQiIGhlaWdodD0iMTIwMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*hTEuxliIs2s_098pdVaOsg.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*mrsat28nAJ7e1PWJcb-KMQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="986" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*mrsat28nAJ7e1PWJcb-KMQ.png" /></p>

<p>海雲台方面（高層ビル）に向かって歩き、交差点に出ると、向かいの右側に有名で美味しい <a href="https://naver.me/x9zcuKNm" target="_blank">塩パン — Jayeondo saltbread</a>（後で買いに戻ります）、左側を海に向かって歩くと釜山スカイの入口があります。</p>

<p><img src="/assets/8ace34a1a3d8/1*mxRI19obHDJEYWgaWpLC4g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*mxRI19obHDJEYWgaWpLC4g.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*kG7OMT38Kq5n4inz0Zi1VQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*kG7OMT38Kq5n4inz0Zi1VQ.jpeg" /></p>

<h4 id="1535-釜山-busan-x-the-sky">~=15:35 釜山 BUSAN X the SKY</h4>

<p><img src="/assets/8ace34a1a3d8/1*wLhiiMFHth1q0M0I52w0BQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*wLhiiMFHth1q0M0I52w0BQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*4GZH5tai41pbv0WbydQBzQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*4GZH5tai41pbv0WbydQBzQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*MZtM_pbelaE_9DSkReik6Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*MZtM_pbelaE_9DSkReik6Q.jpeg" /></p>

<p>海雲台ビーチ側のガラスには柵があり、近づいて写真を撮ることはできません。</p>

<p><img src="/assets/8ace34a1a3d8/1*LphemYMPN0KncWvpEvv-5w.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*LphemYMPN0KncWvpEvv-5w.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*59D8d2G9l56zMvbn3yw55Q.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*59D8d2G9l56zMvbn3yw55Q.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*Naj3fWNQzQthcPQJvr3onA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*Naj3fWNQzQthcPQJvr3onA.jpeg" /></p>

<p>透明なガラスの床の橋がありますが、ガラスがかなり擦り減っていてあまり良い効果はありませんでした。また、透明なガラスのトイレもあります。</p>

<p><img src="/assets/8ace34a1a3d8/1*-H0j9zTeDr4mJ6Cqk3wWfA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*-H0j9zTeDr4mJ6Cqk3wWfA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*8kH5BBvg3v0xYPxl-NknSw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*8kH5BBvg3v0xYPxl-NknSw.jpeg" /></p>

<p>下に進むとカフェやお土産店があり、先ほどのカプセル列車のルートを振り返ることができます。</p>

<p><img src="/assets/8ace34a1a3d8/1*89JfpBVVoL3GcEbkqqMNyQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*89JfpBVVoL3GcEbkqqMNyQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*3MGWqKezW4zdue_uNECOWw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*3MGWqKezW4zdue_uNECOWw.jpeg" /></p>

<p>魚の板ソーセージを一本食べてエネルギー補給（味は普通）。</p>

<p><img src="/assets/8ace34a1a3d8/1*--lNPiay_O4al6tfX5spwg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*--lNPiay_O4al6tfX5spwg.jpeg" /></p>

<p>カフェやお土産屋のほかに、この階には無料の展示もあります。</p>

<h4 id="1600-出発し歩いて塩パン--jayeondo-saltbreadを買いに行く-">~=16:00 出発し、歩いて<a href="https://naver.me/x9zcuKNm" target="_blank">塩パン — Jayeondo saltbread</a>を買いに行く 👍👍👍</h4>

<p><img src="/assets/8ace34a1a3d8/1*w9_aMzKXaNfaz_haZN-XIw.webp" alt="" loading="lazy" decoding="async" width="1200" height="853" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*w9_aMzKXaNfaz_haZN-XIw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*XF58GQnLL6PnuqbvlxDNEQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*XF58GQnLL6PnuqbvlxDNEQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*O8DuQ0ywuuN5fxZXc_0_JQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*O8DuQ0ywuuN5fxZXc_0_JQ.jpeg" /></p>

<p>1セットに6個入りで、1セット買ってホテルで分けて食べました。香ばしくてサクサク、ほんのり塩味が効いていて、とても美味しいと思いました。</p>

<p><img src="/assets/8ace34a1a3d8/1*2oV0hKVku4_AgQI7cf_cag.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*2oV0hKVku4_AgQI7cf_cag.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*8-6mY9FWINdMJiYxpfPZEQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*8-6mY9FWINdMJiYxpfPZEQ.jpeg" /></p>

<p>海雲台には多くの大規模な土木工事が行われており、2030年の万博開催を目指しているように見えます（しかし既に失敗しています）。</p>

<blockquote>
  <p><em>ホテルに戻って少し休憩し、夜に味贊王へ行きます。</em></p>
</blockquote>

<h4 id="1750-到着-味贊王海雲台店--matchandeul-salted-grill-haeundae-branch">17:50 到着 <a href="https://naver.me/5sG3vEe5" target="_blank">味贊王海雲台店 — Matchandeul Salted Grill Haeundae Branch</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*AsOMjouHVz3BRue3olauuw.webp" alt="" loading="lazy" decoding="async" width="943" height="1198" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDMiIGhlaWdodD0iMTE5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*AsOMjouHVz3BRue3olauuw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*O39pGmtLGJIa-bXxK-Nnig.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*O39pGmtLGJIa-bXxK-Nnig.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*52iHV2Dv0vDDxNuqJxYmhg.webp" alt="" loading="lazy" decoding="async" width="484" height="811" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0ODQiIGhlaWdodD0iODExIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*52iHV2Dv0vDDxNuqJxYmhg.png" /></p>

<p>入口に待ち番号発券機があり、メールアドレスを入力すると通知が届きます。17:50頃から少し並び始めました。</p>

<p><img src="/assets/8ace34a1a3d8/1*PQL9i8rdeGLZD0rNLEaLxw.webp" alt="" loading="lazy" decoding="async" width="515" height="682" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTUiIGhlaWdodD0iNjgyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*PQL9i8rdeGLZD0rNLEaLxw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*NNmf9vfpx9sX-EPv-6-MCQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*NNmf9vfpx9sX-EPv-6-MCQ.jpeg" /></p>

<p>ボタンを押すと現在の番号を確認でき、時間になると入場可能の通知メールも届くので便利です。<strong>また、向かい側や隣のビルが工事中なので注意してください。</strong></p>

<h4 id="1825-入場して食事">18:25 入場して食事</h4>

<p>約30分以上待ってから入場しました。</p>

<p><img src="/assets/8ace34a1a3d8/1*7MgY9p6aZMbGejj56iU11A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*7MgY9p6aZMbGejj56iU11A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*1dn6e5L69VTVnrcEfhMvDw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*1dn6e5L69VTVnrcEfhMvDw.jpeg" /></p>

<p>私たちはダブルセット（肉各1つ＋テンジャンチゲ＋釜飯）を注文し、さらにCassビールを1本追加しました。合計で約NT$1,500でした。</p>

<blockquote>
  <p><em>焼いてくれて、美味しいですが、量は少なめで並んで待つ必要があります。</em></p>
</blockquote>

<h4 id="2030-お腹いっぱいになって海雲台大通りへ戻る">~=20:30 お腹いっぱいになって海雲台大通りへ戻る</h4>

<p><img src="/assets/8ace34a1a3d8/1*O2UXV7D8gKQ0hImc8iDnMA.webp" alt="" loading="lazy" decoding="async" width="948" height="1199" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDgiIGhlaWdodD0iMTE5OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*O2UXV7D8gKQ0hImc8iDnMA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*YINokSS0bT-ebB5VXJhW_w.webp" alt="" loading="lazy" decoding="async" width="918" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTgiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*YINokSS0bT-ebB5VXJhW_w.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*PjSGfzXsbc9bYFb1sK18Tw.webp" alt="" loading="lazy" decoding="async" width="943" height="1233" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDMiIGhlaWdodD0iMTIzMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*PjSGfzXsbc9bYFb1sK18Tw.png" /></p>

<p>海雲台の大通りを散歩して消化し、抹茶専門店でアイスクリームを買ってデザートにしました。</p>

<p><img src="/assets/8ace34a1a3d8/1*eEqklwquew6rGg4-Il6FUw.webp" alt="" loading="lazy" decoding="async" width="937" height="1186" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzciIGhlaWdodD0iMTE4NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*eEqklwquew6rGg4-Il6FUw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*XIW1F6tF8P0ExjjlixWKxQ.webp" alt="" loading="lazy" decoding="async" width="1146" height="961" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQ2IiBoZWlnaHQ9Ijk2MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*XIW1F6tF8P0ExjjlixWKxQ.png" /></p>

<p>隣にはOlive Youngの新しいDelight Project専門店があり、たくさん買い込みました。多くの商品が2つ買うと1つ無料で、15,000ウォン以上でその場で免税が受けられます。</p>

<p><img src="/assets/8ace34a1a3d8/1*9eNytaAkCGcIgbOzagwTiQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="833" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgzMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*9eNytaAkCGcIgbOzagwTiQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*hW_N_93CpyyzWCGZ-OtJ4Q.webp" alt="" loading="lazy" decoding="async" width="943" height="1214" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDMiIGhlaWdodD0iMTIxNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*hW_N_93CpyyzWCGZ-OtJ4Q.png" /></p>

<p>再び海雲台ビーチを散策してからホテルに戻って休みました。</p>

<h3 id="day-3-0731-木-青沙浦スパランド海岸列車釜山ヨットツアー">Day 3 07/31 (木) 青沙浦、スパランド、海岸列車、釜山ヨットツアー</h3>

<p>昨日は青沙浦で乗り換えただけで特に散策しなかったので、今日は改めて来ました。</p>

<h4 id="1100-バスに乗って青沙浦へ出発">11:00 バスに乗って青沙浦へ出発</h4>

<p><img src="/assets/8ace34a1a3d8/1*rbpv52Shw77IaUdT2d7-8w.webp" alt="" loading="lazy" decoding="async" width="954" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*rbpv52Shw77IaUdT2d7-8w.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*DJj6wZCG0KRomyT94xO1lA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*DJj6wZCG0KRomyT94xO1lA.jpeg" /></p>

<p>海雲台から青沙浦へ直通するバスはミニバスで、途中で釜山山荘のような小さくて急な坂のある住宅街を通ります。</p>

<h4 id="1130-青沙浦に到着">11:30 青沙浦に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*fRTe_hokNNcPNgX97qZcQw.webp" alt="" loading="lazy" decoding="async" width="1200" height="846" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*fRTe_hokNNcPNgX97qZcQw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*77MdQpIY5lupV8oQ3chyDw.webp" alt="" loading="lazy" decoding="async" width="1200" height="990" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk5MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*77MdQpIY5lupV8oQ3chyDw.png" /></p>

<p>近くで適当に食事ができる店を探して昼食をとりました（<a href="https://naver.me/GlGmYxyY" target="_blank">Gohyang katsu</a>）。私はとんかつサンドイッチを注文しましたが、肉が厚くて柔らかく、価格も手頃でした。</p>

<h4 id="1230-diart-coffee-ハニーバター-トースト">~=12:30 <a href="https://naver.me/GkUJQI6r" target="_blank">DIART COFFEE ハニーバター トースト</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*Su_kwIRgZb18zoMS0Tv0sw.webp" alt="" loading="lazy" decoding="async" width="948" height="1196" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDgiIGhlaWdodD0iMTE5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Su_kwIRgZb18zoMS0Tv0sw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*smtxM51j_tPmnW-RQql09g.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*smtxM51j_tPmnW-RQql09g.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*8XzQQm3AZ0JR7Gr_TfaYxA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*8XzQQm3AZ0JR7Gr_TfaYxA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*6kxh55_key4KL-Tj5V5WNQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*6kxh55_key4KL-Tj5V5WNQ.jpeg" /></p>

<p>昼食を終えて外に出ると、みんなが絶賛する釜山のハニーバター トースト <a href="https://naver.me/GkUJQI6r" target="_blank">DIART COFFEE</a> がありました。トースト（10,000ウォン）とコーヒー（5,500ウォン）を注文して一休みしました。</p>

<p>食べ方は <a href="https://m.site.naver.com/1Abyy" target="_blank">小卡</a> を参考にしてください。とにかくパンを一口大に切り、バターと蜂蜜を均等に塗って食べます。</p>

<blockquote>
  <p><em>蜂蜜は甘すぎず、バターのミルクの香りとサクサクのパンがよく合い、美味しくて飽きません。</em></p>
</blockquote>

<h4 id="1330-青沙浦に戻り海岸列車で尾浦海雲台へ向かう準備">~=13:30 青沙浦に戻り、海岸列車で尾浦（海雲台）へ向かう準備</h4>

<p><img src="/assets/8ace34a1a3d8/1*W-yaVbvzi87W8xZk_cza4g.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*W-yaVbvzi87W8xZk_cza4g.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*VKTdBhWwiPmOoE4eX7pwVw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*VKTdBhWwiPmOoE4eX7pwVw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*dICe7b0tdWsGppYFDADrhQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*dICe7b0tdWsGppYFDADrhQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*fWJrPrMNalY2YbTFk9ct0Q.webp" alt="" loading="lazy" decoding="async" width="950" height="1214" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTAiIGhlaWdodD0iMTIxNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*fWJrPrMNalY2YbTFk9ct0Q.png" /></p>

<p>昨日は使えなかったので、再度釜山パスで海岸列車のチケットを交換しました；ここは途中駅のため、最後列にしか立って乗れませんでした。</p>

<p><img src="/assets/8ace34a1a3d8/1*_a9Gqyx5xSatuoqZVvDwPQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*_a9Gqyx5xSatuoqZVvDwPQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*6ypVO-ZjcG0zkZAuJKC7Mg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*6ypVO-ZjcG0zkZAuJKC7Mg.jpeg" /></p>

<p>途中でいくつかの展望台を通りましたが、暑すぎて降りませんでした。</p>

<h4 id="1355-尾浦ヘウンデ到着">~=13:55 尾浦（ヘウンデ）到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*viDnwtL1r7EWe3K1FtDKiA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*viDnwtL1r7EWe3K1FtDKiA.jpeg" /></p>

<p>海雲台に戻ってからは、徒歩とバスで新世界スパランドへ向かいました。</p>

<h4 id="1430-到着-新世界shinsegae百貨">~=14:30 到着 <a href="https://naver.me/xfYRYAfu" target="_blank">新世界(SHINSEGAE)百貨</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*ZqGLAD3UKpURs3HKbviTwQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="989" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ZqGLAD3UKpURs3HKbviTwQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*WneX4dSsqbfvEps927Zqjw.webp" alt="" loading="lazy" decoding="async" width="925" height="1176" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjUiIGhlaWdodD0iMTE3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*WneX4dSsqbfvEps927Zqjw.png" /></p>

<p>散策せずに、直接1階のSpa Landへ向かいました。</p>

<h4 id="1440-スパランド">14:40 スパランド</h4>

<p>釜山パスでSpa Landを利用する際の交換。</p>

<blockquote>
  <p><a href="https://www.kkday.com/zh-tw/product/12213-busan-spa-land-centum-city-ticket?cid=19365" target="_blank"><em>Passを購入していなくても、Kkdayで事前に購入可能です。</em></a></p>
</blockquote>

<p>入場時に感知リストバンドが渡されます。このリストバンドで靴や衣類を預け、館内で汗蒸幕専用の服に着替えます。また、先にサウナ（三温暖、全裸必須）に行ってから汗蒸幕に行くことも可能です。汗蒸幕の入口は女性更衣室の方向にあります。</p>

<p><img src="/assets/8ace34a1a3d8/1*2UvncJZg2YqeC9pmzSstww.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*2UvncJZg2YqeC9pmzSstww.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*rgOo09p9c0DJFD9h_UH7fQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*rgOo09p9c0DJFD9h_UH7fQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*9oMyMc4jYnkhHcJKydzXJw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*9oMyMc4jYnkhHcJKydzXJw.jpeg" /></p>

<p>1階には日光浴エリア、ネイルサロン、屋台、さまざまな種類の汗蒸幕（夏休みは人が多く、ほぼ満席でした）があり、3階にはレストラン（焼き卵やインスタントラーメンが食べられます）、マッサージ、マッサージチェア、ヨガルームがあります。</p>

<p>サウナの後は日光浴エリアで寝転んで日光浴をしました。ドリンクを一杯注文しました（めっちゃ甘い）。</p>

<blockquote>
  <p><em>場内のすべての支払いはリストバンドの読み取りで行い、最後に退場時に精算します。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>正直に言うと、今回は汗蒸幕を全く体験できませんでした。人が多すぎて大混雑だったので、次回にします。</em></strong></p>
</blockquote>

<h4 id="1700-ヨット桟橋へ集合の準備">17:00 ヨット桟橋へ集合の準備</h4>

<p>18:30の回を予約する場合は、事前に集合場所で点呼を受ける必要があります。</p>

<p><img src="/assets/8ace34a1a3d8/1*I05lgEC-kLYtbw1s_OWJ6Q.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*I05lgEC-kLYtbw1s_OWJ6Q.jpeg" /></p>

<p>出発前に新世界百貨店の地下1階で軽く食べてお腹を満たしました。</p>

<h4 id="地下鉄で冬柏駅dongbaekへ向かう">地下鉄で冬柏駅（Dongbaek）へ向かう</h4>

<p><img src="/assets/8ace34a1a3d8/1*nLZyTcQcoS4NBTV_EozYFA.webp" alt="" loading="lazy" decoding="async" width="721" height="514" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MjEiIGhlaWdodD0iNTE0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*nLZyTcQcoS4NBTV_EozYFA.png" /></p>

<p>駅を出てから桟橋までは約15分歩きます。</p>

<blockquote>
  <p><em>桟橋のこちら側には自動販売機とトイレしかなく、トイレは少し汚れていて混雑し、並ぶ必要があります；<strong>市内で必要なものを購入し、トイレも済ませてから来ることをおすすめします。</strong></em></p>
</blockquote>

<h4 id="1800-ヨット桟橋に到着">~=18:00 ヨット桟橋に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*2IAvf0t9-X64N-VhcqU3Hw.webp" alt="" loading="lazy" decoding="async" width="944" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*2IAvf0t9-X64N-VhcqU3Hw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*gzCg-qoszdj6FPTDnl6OxA.webp" alt="" loading="lazy" decoding="async" width="1200" height="854" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*gzCg-qoszdj6FPTDnl6OxA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*SEdvFIL6AktezC9W238zDA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*SEdvFIL6AktezC9W238zDA.jpeg" /></p>

<p>観光案内所を通り抜けると桟橋の集合場所に到着します。各船会社ごとに異なる桟橋の集合場所があります。</p>

<p><img src="/assets/8ace34a1a3d8/1*XWHxS8z33CPpiugdE2ddVw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*XWHxS8z33CPpiugdE2ddVw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*uGw5fIqLJIJoxtzTpzNm3g.webp" alt="" loading="lazy" decoding="async" width="947" height="1182" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDciIGhlaWdodD0iMTE4MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*uGw5fIqLJIJoxtzTpzNm3g.png" /></p>

<p>約18:15頃に船員が現れ、整列して点呼を始めました。現地で夜間追加料金（一人5,000ウォン）を徴収しました。</p>

<h4 id="1830-海上ヨット出発-">18:30 海上ヨット出発 👍👍</h4>

<p><img src="/assets/8ace34a1a3d8/1*UdLDGZfqHM_HneNjqh6qlA.webp" alt="" loading="lazy" decoding="async" width="951" height="1209" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTEiIGhlaWdodD0iMTIwOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*UdLDGZfqHM_HneNjqh6qlA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*Z52u6yd6i_bwsvmdKECD1A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Z52u6yd6i_bwsvmdKECD1A.jpeg" /></p>

<p>乗船時は救命胴衣を着用し、2階の一番前の席に座ります。</p>

<p><img src="/assets/8ace34a1a3d8/1*SEVJsECS6H4ngAof9V0nQQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*SEVJsECS6H4ngAof9V0nQQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*fLsO9aiXUtVx3vm_etmEaA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*fLsO9aiXUtVx3vm_etmEaA.jpeg" /></p>

<p>ゆっくり走り、あまり揺れずに、広安大橋を渡って進みます。</p>

<blockquote>
  <p><strong><em>しかし、船に酔いやすい方は酔い止め薬を服用することをおすすめします。</em></strong></p>
</blockquote>

<h4 id="大まかなルート図">大まかなルート図：</h4>

<p><img src="/assets/8ace34a1a3d8/1*J0YqfliMZuX7rnrgzKItkA.webp" alt="" loading="lazy" decoding="async" width="1200" height="798" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*J0YqfliMZuX7rnrgzKItkA.png" /></p>

<h4 id="1850-広安里ビーチ到着前">~=18:50 広安里ビーチ到着前</h4>

<p><img src="/assets/8ace34a1a3d8/1*pDMeZQ252T2zQHU4fnsdmg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*pDMeZQ252T2zQHU4fnsdmg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*0xgRuRCfH8hUew63a7fqqg.webp" alt="" loading="lazy" decoding="async" width="1182" height="665" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTgyIiBoZWlnaHQ9IjY2NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*0xgRuRCfH8hUew63a7fqqg.jpeg" /></p>

<p>約20分後に広安里ビーチ前の海域に到着します。多くのSUPを楽しむ観光客が見られます。ここで停泊し花火を打ち上げます。花火はこの時間帯に出航する各ヨットの船員たちが手持ちで打ち上げますが、まだ明るいためあまり見えません。</p>

<p><img src="/assets/8ace34a1a3d8/1*aPIQ_aNeOjF3F0vc_ghnEA.webp" alt="" loading="lazy" decoding="async" width="1200" height="858" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*aPIQ_aNeOjF3F0vc_ghnEA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*xlY1CbhaJm_y2MH2H2x6FA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*xlY1CbhaJm_y2MH2H2x6FA.jpeg" /></p>

<p>途中、スタッフの方もとても親切に写真を撮ってくれます。</p>

<h4 id="1900-帰路">~=19:00 帰路</h4>

<p><img src="/assets/8ace34a1a3d8/1*YFAwnj0StqttQX1mpGD93Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*YFAwnj0StqttQX1mpGD93Q.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*XfSCLtKiHYCFpboyNPiWcg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*XfSCLtKiHYCFpboyNPiWcg.jpeg" /></p>

<p>ちょうど夕焼けが見えました。</p>

<h4 id="1920-陸に戻る">~=19:20 陸に戻る</h4>

<p>陸地に戻ってからバスで海雲台に戻りました。</p>

<h4 id="1935-海雲台に戻る">~=19:35 海雲台に戻る</h4>

<p><img src="/assets/8ace34a1a3d8/1*5fS1FH22njGy1ppRJNvRhQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*5fS1FH22njGy1ppRJNvRhQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*hS21eQGZ-VvsLKqQINEiEw.webp" alt="" loading="lazy" decoding="async" width="932" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*hS21eQGZ-VvsLKqQINEiEw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*nEMJPKds-CrjF2BDsR3ZcA.webp" alt="" loading="lazy" decoding="async" width="1200" height="734" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjczNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*nEMJPKds-CrjF2BDsR3ZcA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*K8XU7m63X0bGVYcaMOwgGQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*K8XU7m63X0bGVYcaMOwgGQ.jpeg" /></p>

<p>海雲台ビーチには市場や屋台があります。</p>

<h4 id="1955-海雲台へ行って食事-焼きうなぎ--pungcheonman-">~=19:55 海雲台へ行って食事 <a href="https://naver.me/GEiuqenG" target="_blank">焼きうなぎ — PUNGCHEONMAN</a> 👍👍</h4>

<p><img src="/assets/8ace34a1a3d8/1*--tFcHDWgpPDD__zrK8Jlg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*--tFcHDWgpPDD__zrK8Jlg.jpeg" /></p>

<p>店内の席は多く、待たずにすぐ入れました。</p>

<p><img src="/assets/8ace34a1a3d8/1*R-kS0zI7e106d0e2SAaMKg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*R-kS0zI7e106d0e2SAaMKg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*CHuWZKV3-zp9Z5vDy3h2kQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*CHuWZKV3-zp9Z5vDy3h2kQ.jpeg" /></p>

<p>私たちはうなぎの蒲焼き、焼き牛肉、冷麺2つ、ビールを注文し、合計でNT$2,387を支払いました。</p>

<p><img src="/assets/8ace34a1a3d8/1*eebei6lY1kzg2ZkEunW1Gw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*eebei6lY1kzg2ZkEunW1Gw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*3v8CcPgaFWmH4190p4q1og.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*3v8CcPgaFWmH4190p4q1og.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*qku3gySyCW3u98SQ7qXA7g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*qku3gySyCW3u98SQ7qXA7g.jpeg" /></p>

<p>焼きウナギはパリッと柔らかくジューシーで、とても美味しく、全く臭みがありません。焼き牛肉の薄切りも悪くないですが普通です。そば冷麺は黒糖のかき氷のようですが、実際は醤油味で氷が細かく入っており、とてもさっぱりして美味しいです。</p>

<p><img src="/assets/8ace34a1a3d8/1*IakblW3IGN6wxf1NkX29Ww.webp" alt="" loading="lazy" decoding="async" width="957" height="1213" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTciIGhlaWdodD0iMTIxMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*IakblW3IGN6wxf1NkX29Ww.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*NUtsqQvPLceti09GjSi1Ew.webp" alt="" loading="lazy" decoding="async" width="947" height="1182" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDciIGhlaWdodD0iMTE4MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*NUtsqQvPLceti09GjSi1Ew.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*NqVaJBSjpavz5Pqaee01Zg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*NqVaJBSjpavz5Pqaee01Zg.jpeg" /></p>

<p>食事の後、また海雲台の大通りを散歩し、海雲台伝統市場へ（海鮮チヂミを食べ忘れてしまった、悔しい！）お土産も購入。明日はいよいよ海雲台を離れます。</p>

<h3 id="day-4-0801-金-南浦洞松島海上ケーブルカー龍宮雲橋甘川洞文化村釜山タワー">Day 4 08/01 (金) 南浦洞、松島海上ケーブルカー、龍宮雲橋、甘川洞文化村、釜山タワー</h3>

<h4 id="0915-南浦洞へ出発">09:15 南浦洞へ出発</h4>

<p><img src="/assets/8ace34a1a3d8/1*amKvoodXorVlvXyKiBALLg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*amKvoodXorVlvXyKiBALLg.jpeg" /></p>

<p>朝早、海雲台を出発して南浦洞へ向かう準備をする。</p>

<h4 id="1030-札嘎其駅に到着hotel-noah-ホテル">~=10:30 札嘎其駅に到着、<a href="https://www.agoda.com/zh-cn/hotel-noah_3/hotel/busan-kr.html" target="_blank">Hotel Noah</a> ホテル</h4>

<p><img src="/assets/8ace34a1a3d8/1*Kq_QYpAk4Kr-F09JJ_FRWQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*Kq_QYpAk4Kr-F09JJ_FRWQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*sMUSi1v4EluBNNT5emHqOg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*sMUSi1v4EluBNNT5emHqOg.jpeg" /></p>

<p>荷物預かり。</p>

<h4 id="biff広場">BIFF広場</h4>

<p><img src="/assets/8ace34a1a3d8/1*cQXerZP_VIvP5ToSBrLgEw.webp" alt="" loading="lazy" decoding="async" width="945" height="1194" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDUiIGhlaWdodD0iMTE5NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*cQXerZP_VIvP5ToSBrLgEw.png" /></p>

<p>ホテルを出て目の前がBIFF広場で、とても賑やかで便利です。</p>

<h4 id="1100-昼食--hongkong-0410-nampo-1st-branch">~=11:00 昼食 — <a href="https://naver.me/G28VhTtY" target="_blank">Hongkong 0410 Nampo 1st Branch</a></h4>

<p>昼近くにBIFF内で適当にレストランを見つけて昼食を取りました。ここは韓国風中華料理の店です。</p>

<p><img src="/assets/8ace34a1a3d8/1*PFYie7L_VFf4E70JCoCjAw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*PFYie7L_VFf4E70JCoCjAw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*YNNdD826iQ8fqvZnDgJQFA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*YNNdD826iQ8fqvZnDgJQFA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ERESHYR_kpkJluI7uTd3CQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*ERESHYR_kpkJluI7uTd3CQ.jpeg" /></p>

<p>揚げ餃子、酢豚（中サイズ、小でも良さそう）、韓国風ジャージャー麺を注文しました。</p>

<p>揚げ餃子は少し脂っこいですが、酢豚は美味しいです。</p>

<h4 id="1215-バス徒歩で松島ケーブルカー駅に到着">12:15 バス+徒歩で松島ケーブルカー駅に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*O-7uqMkqeEY_hnPImCZ4nA.webp" alt="" loading="lazy" decoding="async" width="604" height="729" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDQiIGhlaWdodD0iNzI5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*O-7uqMkqeEY_hnPImCZ4nA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*e07O9sxOWghCiDG4t57fTQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*e07O9sxOWghCiDG4t57fTQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*G55PQci1BikM7kS7jRyBUg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*G55PQci1BikM7kS7jRyBUg.jpeg" /></p>

<p>バスを降りてから約10分歩く必要があり、とても暑いので、先にコンビニで自家製カフェラテを買って涼みます。</p>

<p><img src="/assets/8ace34a1a3d8/1*ntKH7dp9EHgiSQfDiETb1w.webp" alt="" loading="lazy" decoding="async" width="929" height="1189" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjkiIGhlaWdodD0iMTE4OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ntKH7dp9EHgiSQfDiETb1w.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*gMrRyaT7YG7QVkW6vs4aYw.webp" alt="" loading="lazy" decoding="async" width="928" height="1186" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjgiIGhlaWdodD0iMTE4NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*gMrRyaT7YG7QVkW6vs4aYw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*9hyji_BcmpmX8mnbQ_8sYg.webp" alt="" loading="lazy" decoding="async" width="938" height="1196" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzgiIGhlaWdodD0iMTE5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*9hyji_BcmpmX8mnbQ_8sYg.png" /></p>

<p>入ってからカウンターで釜山パスのケーブルカー乗車券と交換します（パスはクリスタルキャビン、<strong>往復なのでチケットは大切に保管してください</strong>）。</p>

<p>チケットを受け取ったら、そのままエスカレーターで上の階へ上がり、ケーブルカーの列に並びます。（キャンディーが配られましたが、私はもらいませんでした）</p>

<h4 id="1225-乗車">12:25 乗車</h4>

<p><img src="/assets/8ace34a1a3d8/1*2rQjr9yJHeMqKNL2WsdftQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*2rQjr9yJHeMqKNL2WsdftQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*zzQbyUo9b66wPcze_M5CTw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*zzQbyUo9b66wPcze_M5CTw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*OL7mGet2prUpedl96EX1PA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*OL7mGet2prUpedl96EX1PA.jpeg" /></p>

<p>5〜6人で1台。</p>

<h4 id="1235-松島に到着">~=12:35 松島に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*qPfpLan9npUSJvb3WCumNA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*qPfpLan9npUSJvb3WCumNA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*iMGGxqNqL_cW6nGUL700ag.webp" alt="" loading="lazy" decoding="async" width="940" height="1176" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDAiIGhlaWdodD0iMTE3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*iMGGxqNqL_cW6nGUL700ag.png" /></p>

<p>出てすぐ右折して下に進みます。</p>

<p><img src="/assets/8ace34a1a3d8/1*OTbo_MgGmzY5e3BUofU85A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*OTbo_MgGmzY5e3BUofU85A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*jeVCIVeLt_fhFSTgRBKjow.webp" alt="" loading="lazy" decoding="async" width="955" height="1194" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTUiIGhlaWdodD0iMTE5NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*jeVCIVeLt_fhFSTgRBKjow.png" /></p>

<p>階段を下りて右に曲がると、すぐに「松島龍宮吊り橋」です。</p>

<h4 id="1240-松島龍宮吊り橋に到着">~=12:40 松島龍宮吊り橋に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*witcQsiZpHm_OvIQKoGY3g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*witcQsiZpHm_OvIQKoGY3g.jpeg" /></p>

<p>隣のチケット売り場で釜山パスを使ってチケットと交換し入場。</p>

<p><img src="/assets/8ace34a1a3d8/1*0vBkG9nJIvyD7hrhYj-xnw.webp" alt="" loading="lazy" decoding="async" width="945" height="1203" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDUiIGhlaWdodD0iMTIwMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*0vBkG9nJIvyD7hrhYj-xnw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*PhNqmy6wBPgUbjY3zRT82w.webp" alt="" loading="lazy" decoding="async" width="360" height="480" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNjAiIGhlaWdodD0iNDgwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*PhNqmy6wBPgUbjY3zRT82w.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*hjmWsaA7pNfx77EXr5M7aQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1001" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMDEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*hjmWsaA7pNfx77EXr5M7aQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*-KX5b9yL0bniAwPYFgXcgw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*-KX5b9yL0bniAwPYFgXcgw.jpeg" /></p>

<p>ここは全く日陰がなく、真夏の太陽の下でとても暑いですが、松島ケーブルカー全体を見渡せます。</p>

<h4 id="1300-松島ケーブルカーに戻りケーブルカーに並んで帰る">~=13:00 松島ケーブルカーに戻り、ケーブルカーに並んで帰る</h4>

<p><img src="/assets/8ace34a1a3d8/1*Og_17fLIQsrceTBxCRxZow.webp" alt="" loading="lazy" decoding="async" width="960" height="1192" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjAiIGhlaWdodD0iMTE5MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Og_17fLIQsrceTBxCRxZow.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*OHD1o7Nau7E8xTUOb1yjeQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*OHD1o7Nau7E8xTUOb1yjeQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*zkbCoM-RhqaU33418vE2aQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*zkbCoM-RhqaU33418vE2aQ.jpeg" /></p>

<h4 id="1325-松島を出発しバス乗り場まで歩く">~=13:25 松島を出発し、バス乗り場まで歩く</h4>

<p><img src="/assets/8ace34a1a3d8/1*RCy2E4mmH3saWnKRoc7xWg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*RCy2E4mmH3saWnKRoc7xWg.jpeg" /></p>

<p>ロープウェイの近くにも展望台がありますが、暑すぎて行きませんでした。</p>

<p>バス停に戻り、市街地へ戻ってからミニバスに乗り換え、甘川洞文化村へ向かいます。</p>

<p><img src="/assets/8ace34a1a3d8/1*zTVKv3tTtOdHSoOj81jtTQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*zTVKv3tTtOdHSoOj81jtTQ.jpeg" /></p>

<h4 id="1420-甘川洞文化村">~=14:20 甘川洞文化村</h4>

<p><img src="/assets/8ace34a1a3d8/1*rn4LG3Z1ckz_GMiNQe-8FA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*rn4LG3Z1ckz_GMiNQe-8FA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*iJV9jBpSfiIbdpOf6t02Kw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*iJV9jBpSfiIbdpOf6t02Kw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*EDPA83YXOSXbRqmWTUzirg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*EDPA83YXOSXbRqmWTUzirg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*Dhi69ZSRcSJyvFgv_Oz5Cw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*Dhi69ZSRcSJyvFgv_Oz5Cw.jpeg" /></p>

<p>写真は撮らず、ただスポットを巡るだけでした。感じとしてはレインボーコミュニティといくつかのカフェがあるだけで、通りすがりにざっと見て、別のバス停からバスに乗ってホテルに戻りました。</p>

<blockquote>
  <p><em>ここでのバスはミニバスで、陽明山のミニバスに似ています。運転手はかなりスピードを出し、乗客も多く混雑しています。</em></p>
</blockquote>

<h4 id="1500-noah-hotel-に戻って休憩">~=15:00 Noah Hotel に戻って休憩</h4>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/ESP5SgZ4MMA" title="Hotel Noah" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p><img src="/assets/8ace34a1a3d8/1*c7JIBKmacB_0FpkD1VSV3A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*c7JIBKmacB_0FpkD1VSV3A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*fAl0cr7HLrPVGIc76JM94Q.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*fAl0cr7HLrPVGIc76JM94Q.jpeg" /></p>

<ul>
  <li>
    <p>部屋の窓からの景色</p>
  </li>
  <li>
    <p>コインランドリーはないと思っていましたが、3階のトイレに無料で使える洗濯機がありました。</p>
  </li>
</ul>

<h4 id="1740-夕食に出発">~=17:40 夕食に出発</h4>

<p><img src="/assets/8ace34a1a3d8/1*IX5LmJYb0y7bIOE2FWW1DQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*IX5LmJYb0y7bIOE2FWW1DQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*4qK7MSMMHkG60tIe-3yoDQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*4qK7MSMMHkG60tIe-3yoDQ.jpeg" /></p>

<p>ホテルから歩いて約10分です。</p>

<h4 id="1750-のど鍋ふた焼肉--moggumung-nampo支店-">~=17:50 <a href="https://naver.me/xHmnku7F" target="_blank">のど鍋ふた焼肉 — Moggumung Nampo支店</a> 👍👍👍</h4>

<p><img src="/assets/8ace34a1a3d8/1*4nvoaUKeXZOVIb1IOCYYXQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*4nvoaUKeXZOVIb1IOCYYXQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*2KHw99GTRvBgKhL2jVZxBw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*2KHw99GTRvBgKhL2jVZxBw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*DZdWxcnw-93O_23CzoNHGg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*DZdWxcnw-93O_23CzoNHGg.jpeg" /></p>

<ul>
  <li>
    <p>特徴は鍋の蓋が焼き皿になっていることです。</p>
  </li>
  <li>
    <p>おかずにはビタミンCが一粒あります（調べたところ、焼肉の前後にビタミンCを摂取すると、活性酸素の発生を抑え、発がんリスクを減らせるそうです）。</p>
  </li>
  <li>
    <p>最低でも3種類の肉が必要で、すべて店員が焼いてくれます。</p>
  </li>
  <li>
    <p>豚肉2人前＋牛肉1人前＋インスタントラーメン2杯＋Cassビールを注文しました。肉は1人前18,000ウォンで、<strong>実際の支払いはNT$1,060でとてもお得でしたし、肉もとても美味しかったです！！大おすすめです。</strong></p>
  </li>
</ul>

<h4 id="-1830-釜山タワーへ徒歩で移動">~= 18:30 釜山タワーへ徒歩で移動</h4>

<p>お腹がいっぱいになった後、釜山タワーまで歩いて消化します。約20分です。</p>

<p><img src="/assets/8ace34a1a3d8/1*sLs757OOzNAkMKeiRv3lPQ.webp" alt="" loading="lazy" decoding="async" width="698" height="539" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2OTgiIGhlaWdodD0iNTM5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*sLs757OOzNAkMKeiRv3lPQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*wrz7_9izA0-r02hyNB38sg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*wrz7_9izA0-r02hyNB38sg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*k3Z6gYsAotOt5OVIdFIKgw.webp" alt="" loading="lazy" decoding="async" width="933" height="1170" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzMiIGhlaWdodD0iMTE3MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*k3Z6gYsAotOt5OVIdFIKgw.png" /></p>

<p>道中は賑やかで、食べ物のレストランがたくさんありました。</p>

<p><img src="/assets/8ace34a1a3d8/1*U8r_Qon2rFimBcnEdWpmyw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*U8r_Qon2rFimBcnEdWpmyw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*Ovz-36q_zBh3L-jFrMdUZQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="833" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgzMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Ovz-36q_zBh3L-jFrMdUZQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*DL3TyNS4bk-sKRx3rNkFqw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*DL3TyNS4bk-sKRx3rNkFqw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*mrV2TAQELoqtWkPK1uj22g.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*mrV2TAQELoqtWkPK1uj22g.jpeg" /></p>

<blockquote>
  <p><strong><em>ナビ設定は実際には — <a href="https://naver.me/GDL5X5TV" target="_blank">龍頭山記念公園入口 Yongdusan Media Park Entrance</a></em></strong> <em>にすべきです。そこにエスカレーターがあります；ここから登ると少し山を登る必要があります（約5分）。</em></p>
</blockquote>

<h4 id="1900-釜山タワー下に到着し日没後に夜景を見るために登るのを待つ">19:00 釜山タワー下に到着し、日没後に夜景を見るために登るのを待つ</h4>

<p><img src="/assets/8ace34a1a3d8/1*q4kM-CGN-dIC7w5NU32a0A.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*q4kM-CGN-dIC7w5NU32a0A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*JcfGi8vcQtevAvPWGNnuMg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*JcfGi8vcQtevAvPWGNnuMg.jpeg" /></p>

<p>期間はまずお土産屋さんを見て回りました。</p>

<h4 id="1930-釜山タワーに登る">19:30 釜山タワーに登る</h4>

<p>1階のカウンターで釜山パスを提示してチケットと交換し、入場します。</p>

<p><img src="/assets/8ace34a1a3d8/1*xA5Zg72P8NEN_tUVyPZMkA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*xA5Zg72P8NEN_tUVyPZMkA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*SOJbuAh7kPr2jx-dl1x1zw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*SOJbuAh7kPr2jx-dl1x1zw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*YCkHak-FlJ-mnq0yQWx-yQ.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*YCkHak-FlJ-mnq0yQWx-yQ.jpeg" /></p>

<p>釜山タワーのチケットでQRコードをスキャンすると、謎解きゲームが遊べます。すべてのパスワードを解くと、小さな賞品がもらえます。（パスワードは後で書いています）</p>

<p><img src="/assets/8ace34a1a3d8/1*JnjlJkLecp-f0MseLSVbwQ.webp" alt="" loading="lazy" decoding="async" width="949" height="1148" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDkiIGhlaWdodD0iMTE0OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*JnjlJkLecp-f0MseLSVbwQ.png" /></p>

<p>上に上がると、すでに多くの人が待っていました。</p>

<p><img src="/assets/8ace34a1a3d8/1*Kmf1d-_Vm4iMYNKmF1sb_g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Kmf1d-_Vm4iMYNKmF1sb_g.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*lIwknEUuQ6jAeggYxZZegA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*lIwknEUuQ6jAeggYxZZegA.jpeg" /></p>

<p>19:45の釜山の夕焼け。</p>

<p><img src="/assets/8ace34a1a3d8/1*iYaorZ3UxxKx0uFa5qpe6A.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*iYaorZ3UxxKx0uFa5qpe6A.jpeg" /></p>

<p>20:00/20:10…光の映像投影と花火がありますが、効果は普通です。</p>

<h4 id="2000-釜山の夜景">20:00 釜山の夜景</h4>

<p><img src="/assets/8ace34a1a3d8/1*DH6uu6N5y8MvhoUoJYt-GQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*DH6uu6N5y8MvhoUoJYt-GQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*9WInxaDdY5aNuL-5CcyuKQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*9WInxaDdY5aNuL-5CcyuKQ.jpeg" /></p>

<h4 id="-2010-タワーを下りる">~= 20:10 タワーを下りる</h4>

<p><img src="/assets/8ace34a1a3d8/1*SYJBo1VeGTPz0_-ba7Okbw.webp" alt="" loading="lazy" decoding="async" width="956" height="1223" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTYiIGhlaWdodD0iMTIyMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*SYJBo1VeGTPz0_-ba7Okbw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*bpHpZ2j7hlGjfUqN24QkXQ.webp" alt="" loading="lazy" decoding="async" width="918" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTgiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*bpHpZ2j7hlGjfUqN24QkXQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*trPGYy37LVKvPbDFepZS6g.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*trPGYy37LVKvPbDFepZS6g.jpeg" /></p>

<p>出発前にも写真を撮れるスポットがたくさんあります。</p>

<h4 id="-2015-記念品交換">~= 20:15 記念品交換</h4>

<p><img src="/assets/8ace34a1a3d8/1*GIz7xVJewRWy35RBleksMw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*GIz7xVJewRWy35RBleksMw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*kUe5ECb7bsWp_Qwh2hlEug.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*kUe5ECb7bsWp_Qwh2hlEug.jpeg" /></p>

<p>下山する前に外の無人券売機（Ticket Box）に行くのを忘れないでください：</p>

<ul>
  <li>
    <p>パスワード入力：<code class="language-plaintext highlighter-rouge">19731121</code>（釜山タワー建設日）</p>
  </li>
  <li>
    <p>証明書を持って外の青い建物の土産物センター（釜山タワーの1階ではありません）で小さな景品と交換できます。</p>
  </li>
</ul>

<h4 id="小さなお土産は小さなカードでいくつかのデザインから選べます私は透明な釜山タワーのカードを選びました">小さなお土産は小さなカードで、いくつかのデザインから選べます。私は透明な釜山タワーのカードを選びました：</h4>

<p><img src="/assets/8ace34a1a3d8/1*jPcatm0ieKrZEYkk75hpmA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*jPcatm0ieKrZEYkk75hpmA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*gpu_v-fM13P4wilbaGzEwA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*gpu_v-fM13P4wilbaGzEwA.jpeg" /></p>

<p>龍頭山公園からずっと下山しました。</p>

<p><img src="/assets/8ace34a1a3d8/1*oDNlLOobzNrq0E5Hue-GHA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*oDNlLOobzNrq0E5Hue-GHA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*y3olhVcaCU5pYyDz3U8lcQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*y3olhVcaCU5pYyDz3U8lcQ.jpeg" /></p>

<blockquote>
  <p><strong><em>ここにエスカレーターがあります！！（上り専用で、下りはありません。一部工事中）</em></strong></p>
</blockquote>

<h4 id="2030-戻る--龍頭山記念公園入口-yongdusan-media-park-entrance">20:30 戻る — <a href="https://naver.me/GDL5X5TV" target="_blank">龍頭山記念公園入口 Yongdusan Media Park Entrance</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*G_jAYR7TS8ESc3ddWf-CpA.webp" alt="" loading="lazy" decoding="async" width="961" height="1195" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjEiIGhlaWdodD0iMTE5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*G_jAYR7TS8ESc3ddWf-CpA.png" /></p>

<p>ここから釜山タワーへ行くのが近いです。</p>

<p><img src="/assets/8ace34a1a3d8/1*gavdcweW2vtAfov9NgR9_w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*gavdcweW2vtAfov9NgR9_w.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*QXT1p_8zTY09QXle3f8JTA.webp" alt="" loading="lazy" decoding="async" width="947" height="1197" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDciIGhlaWdodD0iMTE5NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*QXT1p_8zTY09QXle3f8JTA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*QdwuA16DAl-Abv2AqrjJEw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*QdwuA16DAl-Abv2AqrjJEw.jpeg" /></p>

<p>商店街を散策していると、ここにHBAFのアーモンド専門店がありました。味の種類が一番豊富な場所だと思います。Yellowセット（小袋入り）と、他の珍しい味（ポッピングキャンディ、本当に跳ねる、辛いトッポッキ）、人気の味（はちみつ、オレオ、コーン）をお土産に買いました。</p>

<h4 id="2045-biff広場に戻って夜食を買う">20:45 BIFF広場に戻って夜食を買う</h4>

<p><img src="/assets/8ace34a1a3d8/1*hGy9kfVNX80z2gYTpXsO1A.webp" alt="" loading="lazy" decoding="async" width="958" height="1196" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTgiIGhlaWdodD0iMTE5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*hGy9kfVNX80z2gYTpXsO1A.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*I2_vOk86JV7s2IcRV4nwAw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*I2_vOk86JV7s2IcRV4nwAw.jpeg" /></p>

<p>ここには多くの屋台があり、床にはスターの手形があります。</p>

<h4 id="マッコリ-bhc-フライドチキン--bhc-chicken-busan-nampo-branchbiff広場のすぐそば">マッコリ、 <a href="https://naver.me/xww9nJx2" target="_blank">BHC フライドチキン — BHC Chicken Busan Nampo Branch</a>（BIFF広場のすぐそば）👍👍</h4>

<p><img src="/assets/8ace34a1a3d8/1*ps1VVbDmZzRPf5CZTrzdtQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ps1VVbDmZzRPf5CZTrzdtQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*qf2-1dMVz6KrPmTQRXO0Pw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*qf2-1dMVz6KrPmTQRXO0Pw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*oEo33HTYo8UdkOZ60P3Gxw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*oEo33HTYo8UdkOZ60P3Gxw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*C1NraGTlXNjmzfeCg7-5RA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*C1NraGTlXNjmzfeCg7-5RA.jpeg" /></p>

<p>最後に買って帰って食べました：</p>

<ul>
  <li>
    <p>マッコリ酒：粟酒や酒醸に似ていて、とても美味しい。</p>
  </li>
  <li>
    <p>BHC 骨なしフライドチキン：味付けも鶏肉も柔らかくて、とても美味しい。</p>
  </li>
</ul>

<h4 id="0000-おやすみ南浦">00:00 おやすみ、南浦</h4>

<p><img src="/assets/8ace34a1a3d8/1*Hh1Rxl4e47yN-iFuGxer9g.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*Hh1Rxl4e47yN-iFuGxer9g.jpeg" /></p>

<p>だいたい00:00以降、屋台はすべて閉まります。</p>

<h4 id="day-5-0802-土-ロッテ百貨店ヨンド大橋開通毎週土曜日のみ">Day 5 08/02 (土) ロッテ百貨店、ヨンド大橋開通（毎週土曜日のみ）</h4>

<h4 id="1045-ロッテ百貨店光復店ロッテスーパー--lotte-dept-store-gwangbok-branch-aqua-mall">10:45 <a href="https://naver.me/xWziztAc" target="_blank">ロッテ百貨店光復店、ロッテスーパー — Lotte Dept. Store Gwangbok Branch Aqua Mall</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*cCougQTjZSMEe_nhgbQF2w.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*cCougQTjZSMEe_nhgbQF2w.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*CsRLupeh763WBqVnJ8pQDA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*CsRLupeh763WBqVnJ8pQDA.jpeg" /></p>

<p>大体10:XXに出発し、ロッテ百貨店は10:30から営業開始なので、ゆっくり歩いて向かいました。</p>

<p><img src="/assets/8ace34a1a3d8/1*9fHXV2Og6JodL5Pjad3JDg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*9fHXV2Og6JodL5Pjad3JDg.jpeg" /></p>

<p>まずはB1のフードコートのカフェで適当に軽く朝食をとる。（普通、コーヒーはルンゴ）</p>

<h4 id="1130-デパートをぶらぶら散策開始">11:30 デパートをぶらぶら散策開始</h4>

<p><img src="/assets/8ace34a1a3d8/1*A75a3-GEjeoMSxnuqlFt-w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*A75a3-GEjeoMSxnuqlFt-w.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*Nk9RtTQ2z7ruxWDgKhhIrg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*Nk9RtTQ2z7ruxWDgKhhIrg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*-usgnffatzz53RtQHbC6PA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*-usgnffatzz53RtQHbC6PA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*J957_He9MA3RC16vdzSjbA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*J957_He9MA3RC16vdzSjbA.jpeg" /></p>

<ul>
  <li>
    <p>Kodak 店で数着の服を購入しました（台湾の代行購入より平均でNT$300〜500安いです）。<br />
店頭で直接免税手続きをしてもらえます。</p>
  </li>
  <li>
    <p>携帯扇風機を買いました。<br />
レシートを持ってB1のフードコートにある免税機で免税書類を印刷し、最後に空港で現金で免税を受け取ります。（約NT$60返金可能）</p>
  </li>
</ul>

<p><img src="/assets/8ace34a1a3d8/1*QxFRNLVX2vM0ISZf3vM2-g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*QxFRNLVX2vM0ISZf3vM2-g.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*TxOTSeqke8P2TE0MWWgiPA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*TxOTSeqke8P2TE0MWWgiPA.jpeg" /></p>

<ul>
  <li>デパートでは11時から毎時間ウォーターダンスショーがあり、とても見応えがあります。</li>
</ul>

<h4 id="1230-b1-ダウンタウンハンバーガー">12:30 B1 ダウンタウンハンバーガー</h4>

<p><img src="/assets/8ace34a1a3d8/1*i3upBh9hp-ZjdfMxeskBnQ.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*i3upBh9hp-ZjdfMxeskBnQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*oK7jL0JkiRD69PAlv-fO5Q.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*oK7jL0JkiRD69PAlv-fO5Q.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*1BHaKNhjT3BIOkW4-qnE4g.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*1BHaKNhjT3BIOkW4-qnE4g.jpeg" /></p>

<p>歩き疲れたので、昼時にB1のDowntownバーガーへ行きました。理屈はわかりますが、アメリカンバーガーにもキムチがあるんですね！</p>

<p><img src="/assets/8ace34a1a3d8/1*TvleF3CnUri6-JtSSah9mg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*TvleF3CnUri6-JtSSah9mg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*czdiuWsarXuyo7IfATd7hg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*czdiuWsarXuyo7IfATd7hg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*SCYBfHs65_54TAWjMMssnQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*SCYBfHs65_54TAWjMMssnQ.jpeg" /></p>

<p>お腹がいっぱいになったのでデパートの屋上展望台を散歩しました。（とても日差しが強く、すごく暑かったです）。</p>

<h4 id="1330-百貨店を出て外の影島大橋で開橋を待つ">~=13:30 百貨店を出て外の影島大橋で開橋を待つ</h4>

<p><img src="/assets/8ace34a1a3d8/1*SY6E9kWJ4lQ4WfXaX9Lvww.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*SY6E9kWJ4lQ4WfXaX9Lvww.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*PB-U5oD_Iw1PaNIj9vu1Rw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*PB-U5oD_Iw1PaNIj9vu1Rw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ml5meRbBGO-wiXskpKv7FQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ml5meRbBGO-wiXskpKv7FQ.jpeg" /></p>

<p>外はとても暑く、14:00に近づくにつれて集まる人が増えてきました；その時、<strong>あるアジュンマが近づいてきて「8/2〜30は暑すぎるので夜の20:00に変更！」と言いました！！衝撃！！</strong> そして皆が口伝えで20:00に変更と伝え、徐々に人が散り始めました。</p>

<p><img src="/assets/8ace34a1a3d8/1*GQondkcuwv5QwfzkKZ7QPw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*GQondkcuwv5QwfzkKZ7QPw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*Lyms5xvH6lwxp0hPFF2DuA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Lyms5xvH6lwxp0hPFF2DuA.jpeg" /></p>

<p>後で欄干に掲示された案内布を見つけました。（左側の看板は定期的な時間表です）</p>

<h4 id="1350-ロッテ百貨店ロッテマートへ戻って引き続きぶらぶら散策">13:50 ロッテ百貨店、ロッテマートへ戻って引き続きぶらぶら散策</h4>

<p><img src="/assets/8ace34a1a3d8/1*O6oXHk-CkB8vJ-vxvVIfSQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*O6oXHk-CkB8vJ-vxvVIfSQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*0fkOrRbJw84kNZ_Eu_zuZA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*0fkOrRbJw84kNZ_Eu_zuZA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*e2LIsRj5B6KtM1tS_Pvldw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*e2LIsRj5B6KtM1tS_Pvldw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ndyL7-V4wbHHLtu5uYqxlQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ndyL7-V4wbHHLtu5uYqxlQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*Vi3D5-dWbMN0XVogyhAYBA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Vi3D5-dWbMN0XVogyhAYBA.jpeg" /></p>

<p>ロッテマートでもお土産や化粧品を販売しています（まるでカルフールのようです）。</p>

<h4 id="b1-免税手続き機械">B1 免税手続き機械</h4>

<p><img src="/assets/8ace34a1a3d8/1*VJW26Pss8GIKP_EdOKhPbQ.webp" alt="" loading="lazy" decoding="async" width="930" height="1147" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzAiIGhlaWdodD0iMTE0NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*VJW26Pss8GIKP_EdOKhPbQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*QpYPLAIoTGVwYHZoYljzGQ.webp" alt="" loading="lazy" decoding="async" width="948" height="1199" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDgiIGhlaWdodD0iMTE5OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*QpYPLAIoTGVwYHZoYljzGQ.png" /></p>

<p>鼎泰豊の隣の小道にある免税機を探すのにかなり時間がかかりました。</p>

<ul>
  <li>即時還付でない場合は、ここでレシートのバーコードをスキャンして還付申請書を受け取り、最後に空港で還付金を受け取ります。（少し手間がかかります）</li>
</ul>

<blockquote>
  <p><strong><em>韓国にはGlobal Blue、GLOBAL TAX FREE、Easy Tax Refund、CubeRefund、eTAX FREEといった異なる免税機関があり、それぞれ対応する免税機でしか手続きできないことを初めて知りました</em></strong> <em>；Olive Youngで現金還付可能な機械を見かけましたが、それはGLOBAL TAX FREE用で、私のレシートはCubeRefundだったため、結局空港での還付しかできませんでした。</em></p>
</blockquote>

<h4 id="1635-ホテルに戻って休憩">16:35 ホテルに戻って休憩</h4>

<p><img src="/assets/8ace34a1a3d8/1*ngRJ5SY55QsOVeEuesGIXg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ngRJ5SY55QsOVeEuesGIXg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*IoTCxYVKEGU4JpUwsCMEUQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*IoTCxYVKEGU4JpUwsCMEUQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*hA48uOURihuc-sbE-Qrn3Q.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*hA48uOURihuc-sbE-Qrn3Q.jpeg" /></p>

<p>歩き疲れたらB1で韓国のあずきと桃のお菓子、そして昔ながらのレシピで作ったコンビニの手作りドリンク（アイスカップ＋バナナ牛乳＋無糖ブラックコーヒー）を買い、地下街を通ってホテルに戻り休憩しました。</p>

<h4 id="1900-ホテルを出てbiff-olive-youngを散策する">19:00 ホテルを出てBIFF Olive Youngを散策する</h4>

<p><img src="/assets/8ace34a1a3d8/1*LVHpdVT1I-X7_BStMRVfnQ.webp" alt="" loading="lazy" decoding="async" width="932" height="1192" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzIiIGhlaWdodD0iMTE5MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*LVHpdVT1I-X7_BStMRVfnQ.png" /></p>

<p>海雲台では全く見て回れなかったので、ちょうど時間があったから先に見に来ました。このお店はとても大きく、店員さんもたくさんいて親切でした。</p>

<p><img src="/assets/8ace34a1a3d8/1*urwdAXWOvdtMGRzUZ2cMWw.webp" alt="戦利品" loading="lazy" decoding="async" width="1400" height="1049" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNDkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*urwdAXWOvdtMGRzUZ2cMWw.png" /></p>

<p>戦利品</p>

<h4 id="1940-影島大橋に到着開橋を待つ">19:40 影島大橋に到着、開橋を待つ</h4>

<p><img src="/assets/8ace34a1a3d8/1*JG_o0tkChN-UKCtRdkx8Mw.webp" alt="" loading="lazy" decoding="async" width="1200" height="872" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg3MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*JG_o0tkChN-UKCtRdkx8Mw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ZOT3YuHUnfvKjglbTllFRQ.webp" alt="" loading="lazy" decoding="async" width="896" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4OTYiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ZOT3YuHUnfvKjglbTllFRQ.png" /></p>

<p>橋の下には記念写真の合成ブースがあります。</p>

<p>大体19:50頃から交通規制が始まります。</p>

<h4 id="2000-開橋">20:00 開橋</h4>

<p><img src="/assets/8ace34a1a3d8/1*Zpgsucjjm5BNpq_D4zfh1A.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Zpgsucjjm5BNpq_D4zfh1A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*NTI7_uUkEmOE2SLCN3fclQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*NTI7_uUkEmOE2SLCN3fclQ.jpeg" /></p>

<p>まず橋の下で見て、だいたい20:05頃に開き始めたら移動して上に行きます。</p>

<p><img src="/assets/8ace34a1a3d8/1*h8neY7OqYx6WG5QVgxAEGQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*h8neY7OqYx6WG5QVgxAEGQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*n_oF3q1EJ4xy7iF-_mNIYA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*n_oF3q1EJ4xy7iF-_mNIYA.jpeg" /></p>

<p>影島大橋の歴史を紹介するプロジェクションがありましたが、おそらく初日のプロジェクターの角度が悪く、あまりはっきり見えませんでした。</p>

<h4 id="2015-橋が再び降りて通行再開">20:15 橋が再び降りて、通行再開</h4>

<p><img src="/assets/8ace34a1a3d8/1*CsyWpHHwp2x8lLZfbvXvvA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*CsyWpHHwp2x8lLZfbvXvvA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*gV_RKoppNxGGwl8BMErUkw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*gV_RKoppNxGGwl8BMErUkw.jpeg" /></p>

<h4 id="2030-夕食--ton-black--tempura-nine">20:30 夕食 — <a href="https://naver.me/Fm3VOYcH" target="_blank">Ton Black &amp; Tempura Nine</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*VEY9B-esGVFWEHU-1y5OoA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*VEY9B-esGVFWEHU-1y5OoA.jpeg" /></p>

<ul>
  <li>
    <p>夜、ホテルに戻る途中で適当にとんかつ屋を見つけて食べました（とんかつは相変わらず柔らかくて美味しかったです）。</p>
  </li>
  <li>
    <p>NT$366の実際の利用額</p>
  </li>
</ul>

<h4 id="2150-ホテルに戻って休憩">~=21:50 ホテルに戻って休憩</h4>

<p><img src="/assets/8ace34a1a3d8/1*fd1YC6o2Gytnh_shoUXxdg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*fd1YC6o2Gytnh_shoUXxdg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*O-5YaMfjKPHJ3oCMVfn1UQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*O-5YaMfjKPHJ3oCMVfn1UQ.jpeg" /></p>

<h3 id="day-6-0803日ロッテ百貨店プピョン缶詰市場ペクチョン湾文化村ポクチョンサ寺夜景">Day 6 08/03（日）ロッテ百貨店、プピョン缶詰市場、ペクチョン湾文化村、ポクチョンサ寺夜景</h3>

<blockquote>
  <p><strong><em>今日は時間つぶしにぶらぶら歩いただけなので、内容は参考にしないでください。純粋な記録です。</em></strong></p>
</blockquote>

<h4 id="1000-出かける前にまず食べる--egg-drop">10:00 出かける前にまず食べる — <a href="https://naver.me/5gYr3qdc" target="_blank">Egg Drop</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*Kh1xpKnZV-MMtVanIicSyA.webp" alt="" loading="lazy" decoding="async" width="942" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Kh1xpKnZV-MMtVanIicSyA.png" /></p>

<ul>
  <li>ロッテ百貨店の向かいにある商店街です。</li>
</ul>

<p><img src="/assets/8ace34a1a3d8/1*aRSQiMUWKNfjDtDVZ8V3oQ.webp" alt="" loading="lazy" decoding="async" width="945" height="1196" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDUiIGhlaWdodD0iMTE5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*aRSQiMUWKNfjDtDVZ8V3oQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*MnFVcEjz135UauqnyR5H3Q.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*MnFVcEjz135UauqnyR5H3Q.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*BD26TaxsDjAO3wb9rbeFwQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*BD26TaxsDjAO3wb9rbeFwQ.jpeg" /></p>

<ul>
  <li>
    <p>1階の機械で注文し、番号札を受け取って2階に上がり席を探す（先に席があるか確認した方が良い）</p>
  </li>
  <li>
    <p>約20分待ちました</p>
  </li>
  <li>
    <p>ハムチーズオムレツトースト＋ハッシュポテト＋アイスコーヒーを注文しました：8,400ウォン</p>
  </li>
</ul>

<blockquote>
  <p><em>悪くはないですが、台湾のほうがもっと美味しいブランチがあります。</em></p>
</blockquote>

<h4 id="1100-お腹がいっぱいになってから出発">11:00 お腹がいっぱいになってから出発</h4>

<p><img src="/assets/8ace34a1a3d8/1*p3YDCVRrvV7QQgx6UomwYA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*p3YDCVRrvV7QQgx6UomwYA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*MQgkZeRyQFfcU5Zti1s4eA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*MQgkZeRyQFfcU5Zti1s4eA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*zl6x8Pt3pxiIR94C8KwkIg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*zl6x8Pt3pxiIR94C8KwkIg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*zB10iTHzqS8mD4T678Lgnw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*zB10iTHzqS8mD4T678Lgnw.jpeg" /></p>

<p>ロッテ百貨店へ向かう途中に「Big Shop」という釜山のお土産専門店があり、Boogiや釜山のイメージグッズがたくさんあります。</p>

<h4 id="ロッテ百貨店-光復店ロッテスーパー--lotte-dept-store-gwangbok-branch-aqua-mall"><a href="https://naver.me/xWziztAc" target="_blank">ロッテ百貨店 光復店、ロッテスーパー — Lotte Dept. Store Gwangbok Branch Aqua Mall</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*IlBfn7L4in16Sqh0S9u89A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*IlBfn7L4in16Sqh0S9u89A.jpeg" /></p>

<p>暇だったのでロッテデパートをぶらぶら続けました。</p>

<h4 id="1145-b1-無国食卓-蒸し料理-ロッテデパート-光復店">11:45 B1 <a href="https://naver.me/5YSwvcB0" target="_blank">無国食卓 蒸し料理 ロッテデパート 光復店</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*OebNrqD4ge6viEehCRbprA.webp" alt="" loading="lazy" decoding="async" width="1200" height="851" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*OebNrqD4ge6viEehCRbprA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*TYSdoPRJBzjaNXE9MImmng.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*TYSdoPRJBzjaNXE9MImmng.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*M1rt5vPWP34qVzr4Rwq8OQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*M1rt5vPWP34qVzr4Rwq8OQ.jpeg" /></p>

<p>数日間、濃い味の食事が続いたので、昼食はあっさりしたものを食べたい。</p>

<ul>
  <li>
    <p>ご飯は別途注文してください。</p>
  </li>
  <li>
    <p>もともとあまり味がありません。</p>
  </li>
</ul>

<p>お腹がいっぱいになった後、また少し散策しました。</p>

<h4 id="1250-ロッテ百貨店を出発し天空の目展望台--yeongju-haneul-nun-observatoryへ向かう">12:50 ロッテ百貨店を出発し、<a href="https://naver.me/xYvTULtB" target="_blank">天空の目展望台 — Yeongju Haneul Nun Observatory</a>へ向かう</h4>

<p>特に目的もなく近くをぶらぶらしていたら、<a href="/posts/z-度旅行記/九州自由行-釜山発博多入国の郵輪旅で由布院-大分-福岡を満喫-cb65fd5ab770/">去年行けなかった展望台</a>を見つけました。バスで直行（21分）できるので行ってみました。</p>

<p><img src="/assets/8ace34a1a3d8/1*vzM0d49ldD5u40myXdTgug.webp" alt="" loading="lazy" decoding="async" width="382" height="721" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzODIiIGhlaWdodD0iNzIxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*vzM0d49ldD5u40myXdTgug.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*T8YCaXpAOoHzt08VBNO2zQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*T8YCaXpAOoHzt08VBNO2zQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*zlS5hxZG5BXyZNASUNzXMA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*zlS5hxZG5BXyZNASUNzXMA.jpeg" /></p>

<ul>
  <li>
    <p>釜山のバスはほとんどが最新の電気バスで、エアコンが非常に効いています。</p>
  </li>
  <li>
    <p>経由した場所：<a href="/posts/z-度旅行記/九州自由行-釜山発博多入国の郵輪旅で由布院-大分-福岡を満喫-cb65fd5ab770/">去年通り過ぎた場所：釜山駅</a></p>
  </li>
</ul>

<h4 id="1300-天空の目展望台--yeongju-haneul-nun-observatory">13:00 <a href="https://naver.me/xYvTULtB" target="_blank">天空の目展望台 — Yeongju Haneul Nun Observatory</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*clTNOo-ZktYUKpKKh75heg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*clTNOo-ZktYUKpKKh75heg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*EQMOhh1KhjP0i9bwys0YuQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*EQMOhh1KhjP0i9bwys0YuQ.jpeg" /></p>

<p>バス停で降りて向かい側に渡り、下に行くと見えます。</p>

<p><img src="/assets/8ace34a1a3d8/1*YDfNJ4--5A0Kt0fiScCvVQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*YDfNJ4--5A0Kt0fiScCvVQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*fzBzk65b4cALhHQ3_Ej2ow.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*fzBzk65b4cALhHQ3_Ej2ow.jpeg" /></p>

<p>ここの景色はとても良く、釜山の南浦全体を見渡せます。</p>

<h4 id="富平缶詰市場へ下山--同僚おすすめのthe-literの手搖杯を先に買う">富平缶詰市場へ下山 — <a href="https://naver.me/FMT6cQrZ" target="_blank">同僚おすすめのThe Literの手搖杯を先に買う</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*-B44RvmQkP8ROxbo_ycOpA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*-B44RvmQkP8ROxbo_ycOpA.jpeg" /></p>

<ul>
  <li>おすすめはブルーベリーヨーグルトスムージー（Yogurt Smoothie — Blueberry）のみで、600MLと1,000MLの2サイズがあります。美味しくて暑さを和らげ、甘すぎず飲んでも喉が渇きません。価格は約4,300ウォンです。</li>
</ul>

<h4 id="富平缶詰市場"><a href="https://naver.me/Goi5D3F6" target="_blank">富平缶詰市場</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*V2RiLAAeaBdJUF4RVKtZCg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*V2RiLAAeaBdJUF4RVKtZCg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*o9T02VtSuMwlGadw7Mq1Jg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*o9T02VtSuMwlGadw7Mq1Jg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*9Zbj66ueqAwQvyD6OTvZqQ.webp" alt="" loading="lazy" decoding="async" width="940" height="1196" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDAiIGhlaWdodD0iMTE5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*9Zbj66ueqAwQvyD6OTvZqQ.png" /></p>

<p>缶詰市場には多くの乾物、雑貨、海産物の屋台（まるで市場のよう）があり、範囲がとても広いです。</p>

<h4 id="富平缶詰市場--milgot-小豆バターよもぎ餅-">富平缶詰市場 — <a href="https://naver.me/GEiuXPsf" target="_blank">Milgot</a> 小豆バターよもぎ餅 👍</h4>

<p><img src="/assets/8ace34a1a3d8/1*Wj_6WUHzrJCVCSyo-gsGSw.webp" alt="" loading="lazy" decoding="async" width="951" height="1180" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTEiIGhlaWdodD0iMTE4MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Wj_6WUHzrJCVCSyo-gsGSw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*2Nj6AKmSZkzlQ5SO013W7w.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*2Nj6AKmSZkzlQ5SO013W7w.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*R14q-E0U_yWC9iXarLhRZg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*R14q-E0U_yWC9iXarLhRZg.jpeg" /></p>

<p>おそらく缶詰市場で最も有名なお店で、特徴は赤豆クリームよもぎ餅です。</p>

<ul>
  <li>
    <p>韓国語が話せなかったので、写真を撮って店員に見せるだけでこれを注文しました。</p>
  </li>
  <li>
    <p>店員は、持ち帰ったら冷蔵保存し、食べる前に30分から1時間ほど解凍すると一番美味しいと言っていました。</p>
  </li>
  <li>
    <p>また、塩味のパンも買いましたが、これも美味しかったです！</p>
  </li>
</ul>

<p><img src="/assets/8ace34a1a3d8/1*qm0Wh7MPbrWfst0Y_4eF-A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*qm0Wh7MPbrWfst0Y_4eF-A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*GJ8R6Is85xYOA8HOlA_bQg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*GJ8R6Is85xYOA8HOlA_bQg.jpeg" /></p>

<p>後でホテルに持ち帰って食べました。ヨモギ餅はもちもちした食感で、きな粉とあんこクリームの組み合わせがとても独特でした。少し甘めですが、通りかかったらぜひ試してみてください！</p>

<p><img src="/assets/8ace34a1a3d8/1*XQYb4xKnzk0rEMbMJWlglQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*XQYb4xKnzk0rEMbMJWlglQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*cwJikydjyNJW3SDbudKmOA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*cwJikydjyNJW3SDbudKmOA.jpeg" /></p>

<p>さらにもう一箱<a href="https://naver.me/xww9nJx2" target="_blank">BHCフライドチキン</a>を買って、夜ご飯にしました。</p>

<h4 id="1830-再出発">18:30 再出発</h4>

<p>夕方に休憩を終えて再び出かけました。主に福泉寺で夜景を撮るためで、まずは白浅湾文化村を見に行きました。</p>

<h4 id="1845-白浅湾文化村">18:45 <a href="https://naver.me/FgTvHYSL" target="_blank">白浅湾文化村</a></h4>

<blockquote>
  <p><em>こちらで最も有名なスポットは — <a href="https://naver.me/52chRHd4" target="_blank">景色を眺めながらコーヒーを飲み、足湯を楽しめる — VIEW, FOOT BATH CAFE</a> 足湯カフェです。</em></p>
</blockquote>

<p><img src="/assets/8ace34a1a3d8/1*wFYAic5cJEcssp2DziS85Q.webp" alt="" loading="lazy" decoding="async" width="945" height="1234" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDUiIGhlaWdodD0iMTIzNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*wFYAic5cJEcssp2DziS85Q.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*9xd7-RARtJnwkQUwLqoz2w.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*9xd7-RARtJnwkQUwLqoz2w.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*_bg1OXnenjgxXpfoX3xwog.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*_bg1OXnenjgxXpfoX3xwog.jpeg" /></p>

<p>しかし時間が遅かったため、ざっと見て回るだけになりました。海岸沿いにはカフェや小さな店がたくさんありますが、時間が遅かったせいか人はあまりいませんでした。下の海岸線の遊歩道は工事中で降りて歩くことができませんでした。今日は曇りで景色もあまり良くありません。</p>

<h4 id="1900-福泉寺--bokcheonsa-templeへ向かう">19:00 <a href="https://naver.me/5L7oHSSB" target="_blank">福泉寺 — Bokcheonsa Temple</a>へ向かう</h4>

<p>白浅湾を出発した後、福泉寺へ向かいます。</p>

<p><img src="/assets/8ace34a1a3d8/1*kCU_DP31_Q8oVxfZPA7hOw.webp" alt="" loading="lazy" decoding="async" width="1136" height="908" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTM2IiBoZWlnaHQ9IjkwOCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*kCU_DP31_Q8oVxfZPA7hOw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*7BgsQXSUyo7X3sQnbDpgCQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*7BgsQXSUyo7X3sQnbDpgCQ.jpeg" /></p>

<p>元々地図ではバスは1駅だけだったので歩こうと思いましたが、数歩歩いて諦めました。地図にはバス1駅（1分）と書いてありますが、実際に歩くと20分ほどかかります（全て急な坂道でかなりきついです）。</p>

<ul>
  <li>Yeongdogu 1 または 5 どちらでも可</li>
</ul>

<p><strong>次の駅 <a href="https://naver.me/xzlLlZhM" target="_blank">Sinseon Elementary School</a> まで1駅だけ乗り、あとは歩くしかありません：</strong></p>

<p><img src="/assets/8ace34a1a3d8/1*O0Q9eorhHVOa5e9W69pK2A.webp" alt="" loading="lazy" decoding="async" width="688" height="310" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2ODgiIGhlaWdodD0iMzEwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*O0Q9eorhHVOa5e9W69pK2A.png" /></p>

<p>降りてから呆然としました。依然としてとても急な坂道で、ここからずっと上へ歩きます：</p>

<p><img src="/assets/8ace34a1a3d8/1*KF-K6yfIdIQ_oxTPMFu6TA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*KF-K6yfIdIQ_oxTPMFu6TA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*A232HHlbcIoIpCEE770RhA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*A232HHlbcIoIpCEE770RhA.jpeg" /></p>

<p>小学校を過ぎると、福泉寺の入口が見えます：</p>

<p><img src="/assets/8ace34a1a3d8/1*8ISDSkUNQK1J6SJokF48Zg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*8ISDSkUNQK1J6SJokF48Zg.jpeg" /></p>

<p>ここからが本番で、さらに震えるほどの坂道をずっと登っていくと、ようやく福泉寺に到着します：</p>

<p><img src="/assets/8ace34a1a3d8/1*f7K27vuhRDimn9H-2KB6Hw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*f7K27vuhRDimn9H-2KB6Hw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*DIL09kj3M9GtyrJSHP9G0A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*DIL09kj3M9GtyrJSHP9G0A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*JBWBSHF6GYn6fIuWPd4Dsw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*JBWBSHF6GYn6fIuWPd4Dsw.jpeg" /></p>

<blockquote>
  <p><strong><em>ここは車の通行がありますので、安全に注意してください ⚠️</em></strong></p>
</blockquote>

<h4 id="1925-福泉寺に到着">19:25 福泉寺に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*a9Rw-kNrof1PF3jtwV5Y1A.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*a9Rw-kNrof1PF3jtwV5Y1A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ojagYvbJbUhKBz1JOVOlwA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*ojagYvbJbUhKBz1JOVOlwA.jpeg" /></p>

<blockquote>
  <p><em>約19:25に福泉寺に到着（ほとんど疲れ果てた）、地図では10分となっているが、実際はずっと上り坂で休憩も含めて約25分かかった。</em></p>
</blockquote>

<p>しかし、さらに悲劇的なことに — 彼は閉店しました！彼は閉店しました！彼は閉店しました！</p>

<p>その通りです。福泉寺はあまり公開された観光地ではなく、静かな寺院です。時間になると門が閉まります。同僚の話では、だいたい18:00以降は入場はできても出ることはできず、特に追い出されることはありませんが、閉門時間を過ぎると入場はできません。</p>

<p><img src="/assets/8ace34a1a3d8/1*DgPxNoCjrJWvL1uURfNIJA.webp" alt="" loading="lazy" decoding="async" width="944" height="1248" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDQiIGhlaWdodD0iMTI0OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*DgPxNoCjrJWvL1uURfNIJA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*VsLe3FUcx9XaJ8WTVWjlIg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*VsLe3FUcx9XaJ8WTVWjlIg.jpeg" /></p>

<p>悲劇で、駅の外のロフトからしか景色を見られませんでした。その後、口コミで来た人たちも皆ここに立っていました。</p>

<blockquote>
  <p><strong><em>しかし、住職は私たちが大粒の汗をかいているのを見て、中から氷水を2本投げてくれました。本当に感謝しています。</em></strong></p>
</blockquote>

<p><img src="/assets/8ace34a1a3d8/1*5lpfrhdVVFrsN-O0qrTmQw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*5lpfrhdVVFrsN-O0qrTmQw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*lEg8_dHkPXgVIPbMLGpAVQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*lEg8_dHkPXgVIPbMLGpAVQ.jpeg" /></p>

<p>ここから市街地の景色が見えます。</p>

<p><img src="/assets/8ace34a1a3d8/1*fFLE2v0oSj9z5snHg_KINQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*fFLE2v0oSj9z5snHg_KINQ.jpeg" /></p>

<p>最後にふと夜景を撮ってから山を下りました。最初は他のブロガーの写真を見て来たいと思いました：</p>

<p><img src="/assets/8ace34a1a3d8/1*gcXOAkYiOkfJZLVpHVqQnw.webp" alt="本当に中に入って撮るとこんな感じ" loading="lazy" decoding="async" width="789" height="743" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3ODkiIGhlaWdodD0iNzQzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*gcXOAkYiOkfJZLVpHVqQnw.png" /></p>

<p><a href="https://judyer.com/bstp/" target="_blank">実際に入って撮るとこんな感じ</a></p>

<p>山を下るとずっと下り坂で、真っ暗でした：</p>

<p><img src="/assets/8ace34a1a3d8/1*uYq1hyMs27u89dlhoSsz7A.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*uYq1hyMs27u89dlhoSsz7A.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*qAWrK94KUe0KxtQDv0kAsQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*qAWrK94KUe0KxtQDv0kAsQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*KQ_lF81lFAdeVBQ5FiexTQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*KQ_lF81lFAdeVBQ5FiexTQ.jpeg" /></p>

<p>とても静かな村で、降りてからバスに乗ってチャガルチ駅に戻りました。</p>

<p><img src="/assets/8ace34a1a3d8/1*X0odkWacFr5MXbc1iBV-tg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*X0odkWacFr5MXbc1iBV-tg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*2wUeYbwRYkMnLrNhrTMWLg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*2wUeYbwRYkMnLrNhrTMWLg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*3nwYcNLllFSmQ8zjmiKxjA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*3nwYcNLllFSmQ8zjmiKxjA.jpeg" /></p>

<p>ホテルに戻る前にBIFF広場でかなり行列ができていた<a href="https://naver.me/5eZTZe4y" target="_blank">種子糖餅</a>を買いましたが、油っぽくて甘すぎてあまり美味しくなかったです。</p>

<p><img src="/assets/8ace34a1a3d8/1*dPAGNfr1hlXfTu3CnFl7ng.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*dPAGNfr1hlXfTu3CnFl7ng.jpeg" /></p>

<p>大体22時ごろ、釜山で雨が降り始めました！旅の終わりが近くてよかったです。</p>

<h3 id="day-7-0804-月-釜山西面新世界デパート韓牛">Day 7 08/04 (月) 釜山西面、新世界デパート、韓牛</h3>

<p>朝、出かけて西面駅へ移動。</p>

<h4 id="1045-西面駅に到着">10:45 西面駅に到着</h4>

<p><img src="/assets/8ace34a1a3d8/1*o5yuGlxr94cLNs65fiuL5A.webp" alt="" loading="lazy" decoding="async" width="1400" height="984" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*o5yuGlxr94cLNs65fiuL5A.png" /></p>

<p>到着後、直接地下鉄駅で荷物を預けようと思いました。他の場所では、ロッテ百貨店でも荷物を預けられます。</p>

<blockquote>
  <p><strong><em>こちらの荷物預かりは非常に高額です：朝10時45分に預けて、夜20時10分に受け取りました。</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>6,000ウォン＋7,000ウォン（約NT$280）を請求されました。</em></strong></p>
</blockquote>

<p><img src="/assets/8ace34a1a3d8/1*Wc20JDECq1yHn3CgB1qXFA.webp" alt="" loading="lazy" decoding="async" width="1400" height="998" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Wc20JDECq1yHn3CgB1qXFA.png" /></p>

<p>この駅の地下街にもOlive Youngがあり、また補充買いをしました。</p>

<h4 id="1100-昼食-韓国風-刀削麺--gijang-sonkalguksu">11:00 昼食 韓国風 <a href="https://naver.me/Fr0l0gR5" target="_blank">刀削麺 — Gijang Sonkalguksu</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*sd_qEyJXkxRxFOBwd40Tvg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*sd_qEyJXkxRxFOBwd40Tvg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*GUBEh-TqX2boCuU2I78HKA.webp" alt="" loading="lazy" decoding="async" width="1200" height="846" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*GUBEh-TqX2boCuU2I78HKA.png" /></p>

<p>昼近くになったので、近くの市場で韓国式のカルグクスを食べました。</p>

<p><img src="/assets/8ace34a1a3d8/1*eELPbEa7ehdgUH6X47-C9A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*eELPbEa7ehdgUH6X47-C9A.jpeg" /></p>

<p>メニューの選択は非常にシンプルで、刀削麺と海苔巻きだけです。</p>

<p><img src="/assets/8ace34a1a3d8/1*EsG2Zr3hz1BvZ6ZYMtfplA.webp" alt="" loading="lazy" decoding="async" width="1200" height="861" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*EsG2Zr3hz1BvZ6ZYMtfplA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*B3iHfLVRtZ7zTuzh5pmOag.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*B3iHfLVRtZ7zTuzh5pmOag.jpeg" /></p>

<blockquote>
  <p><em>海苔巻きをシェアし、私はカルグクスを注文しました。麺はコシがあり、冷たくてさっぱりしています。欠点は具（肉）がほとんどなく、炭水化物だけで食べると単調に感じることです。</em></p>
</blockquote>

<p>食事の後、ロッテ百貨店へ戻る。</p>

<h4 id="the-liter-seo-myeon-medical-street-branch"><a href="https://naver.me/FytxtsbC" target="_blank">The Liter Seo-myeon Medical Street Branch</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*2yLbWMPpyCtAruEp2Cz46g.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*2yLbWMPpyCtAruEp2Cz46g.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*i4mbPG5JVPgWfVZvr40MJg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*i4mbPG5JVPgWfVZvr40MJg.jpeg" /></p>

<p>もう一杯リットルサイズのブルーベリースムージーヨーグルトを買ってさっぱりしました。</p>

<ul>
  <li>ここのアジュンマはとても親切です。</li>
</ul>

<h4 id="ロッテ百貨店--釜山本店-lotte-dept-store-busan-main-branch"><a href="https://naver.me/GA868sJB" target="_blank">ロッテ百貨店 — 釜山本店 Lotte Dept. Store Busan Main Branch</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*VmJEjJZMfCoxu_HLUxnTIA.webp" alt="" loading="lazy" decoding="async" width="952" height="1186" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTIiIGhlaWdodD0iMTE4NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*VmJEjJZMfCoxu_HLUxnTIA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*JnKRh6VL4zQAj5DN0QjOPw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*JnKRh6VL4zQAj5DN0QjOPw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*lBdiaq_smyUqUNRW1ZTLYg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*lBdiaq_smyUqUNRW1ZTLYg.jpeg" /></p>

<p>私はとても回りにくいと感じました。昨日のロッテ百貨店・光復店よりも回りにくく、フロアも店舗数も少ないです。<br />
<strong>唯一の利点は、上階に大きな公共休憩スペースがあり、充電や休憩ができることです。</strong></p>

<p><img src="/assets/8ace34a1a3d8/1*FIKndhK0XDcFCTNeGi9myA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*FIKndhK0XDcFCTNeGi9myA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*HrvD0lkdT605U-UVMyqdnw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*HrvD0lkdT605U-UVMyqdnw.jpeg" /></p>

<p>ここにも釜山のお土産店がありますが、南浦の店より品揃えがかなり少ないです。</p>

<p><img src="/assets/8ace34a1a3d8/1*hSXu5dj5gWdLB99e5TaHXA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*hSXu5dj5gWdLB99e5TaHXA.jpeg" /></p>

<p>レゴショップを見終わって、行く場所が分からなかったので、バスに乗って新世界百貨店に行きました。</p>

<blockquote>
  <p><em>西面のもう一つのNCデパートは閉店しました。<strong>他に行くなら田浦のカフェ通りがおすすめです。たくさんの小さなお店があり（東区の雰囲気に似ています）が、男性にはあまり興味が湧かないかもしれません。</strong></em></p>
</blockquote>

<h4 id="釜山はいい">釜山はいい！</h4>

<p><img src="/assets/8ace34a1a3d8/1*FtpmNOEbpZm_wqMEE0XZXA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*FtpmNOEbpZm_wqMEE0XZXA.jpeg" /></p>

<blockquote>
  <p><em>釜山のあちこちで「Busan is good」というスローガンを見かけますが、実際に旅行してみて本当に良いと感じました。バスが非常に多く、交通も便利で、バスは新しくて涼しく、物価も安くて食べ物も美味しいです。</em></p>
</blockquote>

<h4 id="新世界shinsegaeデパート--shinsegae-centum-city-"><a href="https://naver.me/xfYRYAfu" target="_blank">新世界(SHINSEGAE)デパート — Shinsegae Centum City</a> 👍👍👍</h4>

<p>数日前はSpa Landだけ行って、ゆっくり見られなかったので、今回はゆっくり見に来ました。</p>

<p><img src="/assets/8ace34a1a3d8/1*_Z3co8etvvt8uJ6IW2WBZg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*_Z3co8etvvt8uJ6IW2WBZg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*U0WsMct8QALuKAQXMVp-fQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*U0WsMct8QALuKAQXMVp-fQ.jpeg" /></p>

<blockquote>
  <p><strong><em>新世界デパート超大型（金氏世界記録第一位）</em></strong> <em>、たくさんのものを見ることができます。</em></p>
</blockquote>

<blockquote>
  <p><em>足りなければ隣にも<a href="https://naver.me/5b0d0jtI" target="_blank">ロッテ百貨店 センタムシティ店 — Lotte Dept. Store Centum City Branch</a>があります。</em></p>
</blockquote>

<p><img src="/assets/8ace34a1a3d8/1*QGugJUaJZPoHgPEOElZ4uA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*QGugJUaJZPoHgPEOElZ4uA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*wFK6WxUwNb_DeaQyLu_dtA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*wFK6WxUwNb_DeaQyLu_dtA.jpeg" /></p>

<p>2つの建物で構成されており、それぞれに複数の階があり、各階の面積も広いです。ついでに釜山のLa Lebo（一階にあります）の価格を記録しました。</p>

<p><img src="/assets/8ace34a1a3d8/1*yCeQQeere4hq9i_JBXxVug.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*yCeQQeere4hq9i_JBXxVug.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*HCpT3BycowwHj4YH7T3kZg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*HCpT3BycowwHj4YH7T3kZg.jpeg" /></p>

<p>この建物の屋上には、ZOORAJIの無料恐竜公園があり、子供を遊ばせることができます。</p>

<p><img src="/assets/8ace34a1a3d8/1*oFC6DVRe9pA7T-R5TUG0HA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*oFC6DVRe9pA7T-R5TUG0HA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ZRWtwouGGpGv9F2cvFCz_A.webp" alt="" loading="lazy" decoding="async" width="922" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ZRWtwouGGpGv9F2cvFCz_A.png" /></p>

<p>ぶらぶらと歩いただけですが、基本的にすべてのブランド、すべてのタイプの店舗が揃っています。</p>

<p><strong>別の建物の1階にShake Shackがあったので、これは食べないわけにはいかない：</strong></p>

<h4 id="shake-shack-busan-centum"><a href="https://naver.me/GCgugmaP" target="_blank">SHAKE SHACK BUSAN CENTUM</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*kuCM6Mh79ZFYGXtuk2qv7Q.webp" alt="" loading="lazy" decoding="async" width="1200" height="841" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*kuCM6Mh79ZFYGXtuk2qv7Q.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*w8wX3ItxckiitSpt-SPH9Q.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*w8wX3ItxckiitSpt-SPH9Q.jpeg" /></p>

<p>これを注文しましたが、サクサクのチキンセットです。Shake Shackは看板メニューだけでなく、チキンもジューシーで美味しいと思います。</p>

<p><img src="/assets/8ace34a1a3d8/1*aVPzCfKsq8FJ5xpyl0Wleg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*aVPzCfKsq8FJ5xpyl0Wleg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*3WaFG6qy3Eg9mm9BvXbLxg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*3WaFG6qy3Eg9mm9BvXbLxg.jpeg" /></p>

<p>呼び出し器に少し問題があったようで、実は早く準備できていたのに鳴りませんでした。</p>

<blockquote>
  <p><em>懐かしい味わい。</em></p>
</blockquote>

<blockquote>
  <p><em>旅行記: <a href="https://zhgchg.li/posts/aacd5f5cacd1/#1200-shake-shack" target="_blank">大阪 Shack Shake</a> / <a href="https://zhgchg.li/posts/b7e7c0938985/#central-world" target="_blank">バンコク Shake Shack</a></em></p>
</blockquote>

<h4 id="1700-新世界百貨を出発">~=17:00 新世界百貨を出発</h4>

<h4 id="1745-田浦駅西面に戻る">~=17:45 田浦駅（西面）に戻る</h4>

<p>夜に韓牛を食べる準備をしています。</p>

<p><img src="/assets/8ace34a1a3d8/1*A18rMP1xmxzXPrQ9RPTkDQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*A18rMP1xmxzXPrQ9RPTkDQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ytbdvCf_b5ARZf_PyPolmQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*ytbdvCf_b5ARZf_PyPolmQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*vS3dZ4vmhuLZLOkifzpZ4Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*vS3dZ4vmhuLZLOkifzpZ4Q.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*6cr53hsYgiwQJNrgtETIPQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*6cr53hsYgiwQJNrgtETIPQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*3Sg_E9SpDVQi2sIZs5HR7w.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*3Sg_E9SpDVQi2sIZs5HR7w.jpeg" /></p>

<p>田浦駅を出ると、田浦カフェ通りへの案内板が見えます。駅の外には一軒家のOlive Youngがあります。</p>

<p>田浦にはカフェや小さなお店がたくさんあり、東区のような雰囲気です。</p>

<h4 id="花肉店-田浦店--flowerbeefhouse"><a href="https://naver.me/Gj7G7BxZ" target="_blank">花肉店 田浦店 — flowerbeefhouse</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*C7814gYWbA1ajdvCX24HBA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*C7814gYWbA1ajdvCX24HBA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*6lXBVu2a8ooPredaeD98YA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*6lXBVu2a8ooPredaeD98YA.jpeg" /></p>

<p>少し東大門のインスタ映えするお店の雰囲気で、<a href="https://www.catchtable.net/zh-TW/shop/busan_kosaljip?operationType=REMOTE_WAITING_GLOBAL" target="_blank">CatchTableで事前予約</a>しておいてよかったです。現地では席がありませんでした。</p>

<p><img src="/assets/8ace34a1a3d8/1*0MfOvlWLctZiRYYM9YI2Ow.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*0MfOvlWLctZiRYYM9YI2Ow.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*dODWMoS7WzgH-siJ6pjpbA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*dODWMoS7WzgH-siJ6pjpbA.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*IknycW3IPMrRvAW5jl0aZw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*IknycW3IPMrRvAW5jl0aZw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*nXobUwdMajACPXrjnt4M8w.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*nXobUwdMajACPXrjnt4M8w.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*MoSNzb94xyAqw7GFRHdxYA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*MoSNzb94xyAqw7GFRHdxYA.jpeg" /></p>

<blockquote>
  <p><em>韓牛セット＋ジャージャー麺＋Cassビールを注文しました。韓牛は柔らかいですが、あまり牛肉の味がせず、普通だと思いました。<strong>価格は実際にNT$2,458で、コスパはあまり良くありません</strong>。数日前に食べた喉鍋蓋焼肉の方が良かったです。</em></p>
</blockquote>

<blockquote>
  <p><em>良い点は写真がきれいに撮れること、店員が親切で中国語も話せることです。</em></p>
</blockquote>

<h4 id="1915-お腹いっぱいで西面駅へ戻る">19:15 お腹いっぱいで西面駅へ戻る</h4>

<p><img src="/assets/8ace34a1a3d8/1*6p05-utFJo4ZG1eFY6yNdQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*6p05-utFJo4ZG1eFY6yNdQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*OJJd1Cu8EacCLHW4NqKJzQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="986" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*OJJd1Cu8EacCLHW4NqKJzQ.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*b-EarSDTdr74ICykPiQrKw.webp" alt="" loading="lazy" decoding="async" width="1200" height="837" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgzNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*b-EarSDTdr74ICykPiQrKw.png" /></p>

<p>田浦から西面にかけては、本当にたくさんの小さなお店やカフェがあり、ZARAも見かけました。</p>

<h4 id="西面駅に戻ってからロッテ百貨店b1のフードコートで食べ物を買い空港近くのホテルへ向かう準備をする">西面駅に戻ってからロッテ百貨店B1のフードコートで食べ物を買い、空港近くのホテルへ向かう準備をする。</h4>

<p><img src="/assets/8ace34a1a3d8/1*w_NQLTD-KKle0HD3xlyngw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*w_NQLTD-KKle0HD3xlyngw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*Rifq7iofXWw4XwV4irb2kQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="875" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg3NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Rifq7iofXWw4XwV4irb2kQ.png" /></p>

<p>ここにもスーパーがあり、最後にこのたこ焼きを買ってホテルで食べました。一番右の韓国風味を選びました。</p>

<h4 id="2030-空港ホテルへ移動">~=20:30 空港ホテルへ移動</h4>

<p><img src="/assets/8ace34a1a3d8/1*rAoS5socLEE80cN-joYtPg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*rAoS5socLEE80cN-joYtPg.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*D0WhmbgOA3EgJVJvW0S_TQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*D0WhmbgOA3EgJVJvW0S_TQ.jpeg" /></p>

<blockquote>
  <p><em>今回は逆方向の伽倻大学へ。同じく火曜日で、まるで先週の火曜日に釜山に着いた自分を見ているようだった。</em></p>
</blockquote>

<h4 id="2100-到着-air-sky-hotel">~=21:00 到着 <a href="https://naver.me/FnViVS4g" target="_blank">AIR SKY HOTEL</a></h4>

<p><img src="/assets/8ace34a1a3d8/1*Uv0KMnohG6_icObDYCwnoQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*Uv0KMnohG6_icObDYCwnoQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*A1HoGDP-gPzEhYhr7jBa-Q.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*A1HoGDP-gPzEhYhr7jBa-Q.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*ZO4RT_vb0kK09_OwDQCfow.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*ZO4RT_vb0kK09_OwDQCfow.jpeg" /></p>

<p>ホテルは空港の一つ手前の駅、西釜山流通地区駅にあり、向かい側にCUとGS25のコンビニがあります。</p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/KCmYPL1Joko" title="AIR SKY HOTEL (Busan)" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p><img src="/assets/8ace34a1a3d8/1*MmEJgGoFwwQ58ZeA01MznQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*MmEJgGoFwwQ58ZeA01MznQ.jpeg" /></p>

<blockquote>
  <p><em>この部屋とバスルームは3日間で最大かつ設備が最も充実していますが、私たちはただ一泊の通過者でした。</em></p>
</blockquote>

<p>部屋の窓から直接飛行機の離着陸が見えます。</p>

<p><img src="/assets/8ace34a1a3d8/1*1o095_AJ41otB1aOuQrdiw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*1o095_AJ41otB1aOuQrdiw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*DqayI4Jguehj-4uKyeUkEw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*DqayI4Jguehj-4uKyeUkEw.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*s7ieNDtJQZQ8SdCa8FnYEg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*s7ieNDtJQZQ8SdCa8FnYEg.jpeg" /></p>

<p>コンビニで桃のお酒を買って、さっき買ったたこ焼きと一緒に楽しみました。このたこ焼きはとても美味しいと思います。持ち帰った時には少し柔らかくなっていましたが、黒いイカ墨ベースで、台湾のたこ焼きのカリッと感と韓国風の辛いソースが合わさって、とても美味しかったです。😋</p>

<h4 id="day-8-0805-火-釜山金海国際空港帰路">Day 8 08/05 (火) 釜山金海国際空港、帰路</h4>

<p>時間はあっという間に過ぎ、8日間の釜山旅行も終わりを迎えます。最終日は空港へ行くだけの予定です。</p>

<p>ホテルを出て1駅で空港に到着（約10分）。</p>

<p><img src="/assets/8ace34a1a3d8/1*Dww8cdw_xtLtDoh2R13GNA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Dww8cdw_xtLtDoh2R13GNA.jpeg" /></p>

<p>空港に到着したら、直接2階の国際線出発フロアへ。</p>

<blockquote>
  <p><em>朝はまだ眠くて、ついでに次回の入国審査を早く通るための<a href="https://www.instagram.com/reel/C8MojavSlZ2/" target="_blank">SES申請</a>を忘れてしまった。</em></p>
</blockquote>

<h4 id="免税手続き">免税手続き</h4>

<p>もし免税書類があれば、<a href="https://www.funliday.com/posts/2024-korea-tax-refund/" target="_blank">この記事</a> を参考に手続きをしてください。<br />
私の免税書類はなくしてしまいました…</p>

<p><img src="/assets/8ace34a1a3d8/1*teDaGZTayKhkL2N84UJ25A.webp" alt="" loading="lazy" decoding="async" width="1400" height="988" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*teDaGZTayKhkL2N84UJ25A.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*pW5hYSUPeitfaOU9aYqklQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*pW5hYSUPeitfaOU9aYqklQ.jpeg" /></p>

<p>2階の端にはたくさんのセルフチェックイン機があり、ここでチェックインや座席指定ができます。3階にも多くの飲食店やショップがあります。</p>

<p><img src="/assets/8ace34a1a3d8/1*8qabU_7i8fR_lKUelRAukw.webp" alt="" loading="lazy" decoding="async" width="1200" height="791" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*8qabU_7i8fR_lKUelRAukw.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*CqJalfOGffMcPy86EiF2NQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="689" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY4OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*CqJalfOGffMcPy86EiF2NQ.png" /></p>

<p>カウンターは一番端のDに割り当てられました。</p>

<p><img src="/assets/8ace34a1a3d8/1*Fe08xzMZ2pZa1ZLJz0i5qQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Fe08xzMZ2pZa1ZLJz0i5qQ.jpeg" /></p>

<ul>
  <li>
    <p>釜山航空の無料手荷物許容量は15KGのみです。</p>
  </li>
  <li>
    <p>携帯用モバイルバッテリーがジッパーバッグに入っているか確認します。</p>
  </li>
  <li>
    <p><strong>荷物を預けたら必ずそのエリアで5分間待って、問題がないか確認してください</strong><br />
その日は誰かがずっと放送で呼ばれていました…</p>
  </li>
</ul>

<h4 id="-0930-出国待機">~= 09:30 出国待機</h4>

<p><img src="/assets/8ace34a1a3d8/1*zp0SV0ILqoWylQLYr0S-uA.webp" alt="" loading="lazy" decoding="async" width="1400" height="958" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk1OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*zp0SV0ILqoWylQLYr0S-uA.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*5xLQvy-TjwOBT2RAmlzq6g.webp" alt="" loading="lazy" decoding="async" width="1200" height="843" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*5xLQvy-TjwOBT2RAmlzq6g.png" /></p>

<p><img src="/assets/8ace34a1a3d8/1*6GHIaGkDU8ajLtBZFc5KdA.webp" alt="" loading="lazy" decoding="async" width="1200" height="1185" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjExODUiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/8ace34a1a3d8/1*6GHIaGkDU8ajLtBZFc5KdA.png" /></p>

<blockquote>
  <p><em>出国ロビーは広くなく、一列だけです。免税店が数軒とコンビニ、カフェがあり、少しだけ食べ物を販売しています。（お腹が空いている場合は、出国前に外で食事を済ませることをおすすめします）</em></p>
</blockquote>

<blockquote>
  <p><strong><em>軍民共用空港のため、外の飛行機は撮影できません。</em></strong></p>
</blockquote>

<p><img src="/assets/8ace34a1a3d8/1*jeZ-QLfYxlbkCFR3s9_6IQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*jeZ-QLfYxlbkCFR3s9_6IQ.jpeg" /></p>

<p><img src="/assets/8ace34a1a3d8/1*oKbFo2YD2LVe80YMI5odeQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*oKbFo2YD2LVe80YMI5odeQ.jpeg" /></p>

<p>何を買うか分からず、コンビニでGDのお酒を2本買って台湾に持ち帰りました。</p>

<h4 id="1107-出発遅延1158-早着">11:07 出発遅延、11:58 早着</h4>

<p><img src="/assets/8ace34a1a3d8/1*PEiW_t5NUyQw-EGRq-SyZg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*PEiW_t5NUyQw-EGRq-SyZg.jpeg" /></p>

<h4 id="釜山旅行大成功">釜山旅行大成功！</h4>

<p><img src="/assets/8ace34a1a3d8/1*Oz4R-jMiTOqh0Qa-rh6cHg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/8ace34a1a3d8/1*Oz4R-jMiTOqh0Qa-rh6cHg.jpeg" /></p>

<h4 id="戦利品">戦利品</h4>

<p><img src="/assets/8ace34a1a3d8/1*mANxdMpisGZuM1PYkslrxg.webp" alt="" loading="lazy" decoding="async" width="968" height="812" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjgiIGhlaWdodD0iODEyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/8ace34a1a3d8/1*mANxdMpisGZuM1PYkslrxg.jpeg" /></p>

<p>あまり買い物はしませんでした。</p>

<h4 id="ご覧いただきありがとうございます">ご覧いただきありがとうございます</h4>

<blockquote>
  <p>もし私の旅行記を気に入っていただけたら、以下のプロモーションリンクから <a href="https://www.kkday.com/zh-tw/product/138477-visit-busan-pass-discount-free-attractions?cid=19365" target="_blank">韓国釜山通行証 VISIT BUSAN PASS</a> をご購入ください。私に一部の収益が還元されます。ありがとうございます。</p>
</blockquote>

<h3 id="その他の旅行記">その他の旅行記</h3>

<ul>
  <li>
    <p><a href="/posts/z-度旅行記/九州自由行-釜山発博多入国の郵輪旅で由布院-大分-福岡を満喫-cb65fd5ab770/"><strong>[旅行記] 2024 九州再訪 9日間自由旅行、釜山経由→博多クルーズ入国</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/山陰島根出雲松江鳥取関西7日自由行-交通1000km-歩数10万歩の旅程ガイド-aacd5f5cacd1/">[旅行記] 2024 山陰広域地域 島根 出雲 松江 鳥取 姫路 大阪 神戸 7日間一人旅自由行</a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/九州自由行-福岡-長崎-熊本を巡る10日間の独り旅ガイド-d78e0b15a08a/">[旅行記] 2023 九州 10日間の自由旅行一人旅</a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/">[旅行記] 2023 広島・岡山 6日間の自由旅行</a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/名古屋一日快閃自由行-樂桃航空機票攻略と観光スポット紹介-7b8a0563c157/">[旅行記] 9/11 名古屋日帰り弾丸ツアー</a></p>
  </li>
  <li>
    <p>[旅行記] <a href="/posts/z-度旅行記/東京自由行-5日間の観光-グルメ-宿泊情報を徹底解説-9da2c51fa4f2/">2023 東京 5日間自由旅行</a></p>
  </li>
  <li>
    <p>[旅行記] <a href="/posts/z-度旅行遊記/京阪神自由行-8日間の京都-大阪-神戸旅行完全ガイド-食事-宿泊-交通情報を網羅-76d66c2e34af/">2023 京阪神 8日間自由旅行</a></p>
  </li>
</ul>

<p><em><a href="https://medium.com/ztravel/%E9%81%8A%E8%A8%98-2025-%E9%9F%93%E5%9C%8B%E9%87%9C%E5%B1%B1-8-%E5%A4%A9-7-%E5%A4%9C%E8%87%AA%E7%94%B1%E8%A1%8C-8ace34a1a3d8" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>を使って変換しました。</em></p>]]></content>
  </entry><entry>
    <title type="html">Google Offerwall 廣告｜内容クリエイター向け新収益モデルを徹底解説</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/google-offerwall-%E5%BB%A3%E5%91%8A-%E5%86%85%E5%AE%B9%E3%82%AF%E3%83%AA%E3%82%A8%E3%82%A4%E3%82%BF%E3%83%BC%E5%90%91%E3%81%91%E6%96%B0%E5%8F%8E%E7%9B%8A%E3%83%A2%E3%83%87%E3%83%AB%E3%82%92%E5%BE%B9%E5%BA%95%E8%A7%A3%E8%AA%AC-ba132457e6a5/" rel="alternate" type="text/html" title="Google Offerwall 廣告｜内容クリエイター向け新収益モデルを徹底解説" />
    <published>2025-07-24T16:15:09+08:00</published>
    <updated>2025-07-24T16:26:29+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ba132457e6a5</id><summary type="html">Google Offerwall広告で既存トラフィックを活用し、視聴後アクセス制限や少額支援を実現。コンテンツ収益化の課題を解決し、安定した収入増加を目指せます。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="iosアプリ開発" /><category term="google広告" /><category term="オファーウォール" /><category term="googleアドセンス" /><category term="jekyll" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/ba132457e6a5/1*fBIJDsQ994Wn0JNyPDJt8Q.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/google-offerwall-%E5%BB%A3%E5%91%8A-%E5%86%85%E5%AE%B9%E3%82%AF%E3%83%AA%E3%82%A8%E3%82%A4%E3%82%BF%E3%83%BC%E5%90%91%E3%81%91%E6%96%B0%E5%8F%8E%E7%9B%8A%E3%83%A2%E3%83%87%E3%83%AB%E3%82%92%E5%BE%B9%E5%BA%95%E8%A7%A3%E8%AA%AC-ba132457e6a5/"><![CDATA[<h3 id="google-offerwall-広告--コンテンツクリエイターの新しい収益オプション">Google Offerwall 広告 — コンテンツクリエイターの新しい収益オプション</h3>

<p>Google Offerwall 広告の概要と試用について。既存のトラフィックコンテンツを、小額の支援や広告視聴後にアクセス制限する形で素早く変換できます。</p>

<h3 id="ライブデモ"><a href="/posts/zrealm開発/google-offerwall-廣告-内容クリエイター向け新収益モデルを徹底解説-ba132457e6a5/">ライブデモ</a></h3>

<p><img src="/assets/ba132457e6a5/1*V4LD8JJoor7SusoHX01_eQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="994" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk5NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*V4LD8JJoor7SusoHX01_eQ.png" /></p>

<p><img src="/assets/ba132457e6a5/1*fBIJDsQ994Wn0JNyPDJt8Q.webp" alt="https://zhgchg.li/posts/ba132457e6a5/" loading="lazy" decoding="async" width="1400" height="973" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk3MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*fBIJDsQ994Wn0JNyPDJt8Q.png" /></p>

<p><a href="/posts/zrealm開発/google-offerwall-廣告-内容クリエイター向け新収益モデルを徹底解説-ba132457e6a5/">https://zhgchg.li/posts/ba132457e6a5/</a></p>

<blockquote>
  <p><strong><em>ライブデモ -&gt; <a href="/posts/zrealm開発/google-offerwall-廣告-内容クリエイター向け新収益モデルを徹底解説-ba132457e6a5/">https://zhgchg.li/posts/ba132457e6a5/</a></em></strong></p>
</blockquote>

<h3 id="google-offerwall-広告">Google Offerwall 広告</h3>

<p><img src="/assets/ba132457e6a5/1*DNW0ylu9LHLs4ztWVzw3UQ.webp" alt="&lt;https://support.google.com/admanager/answer/13860694?hl=zh-Hant&gt;" loading="lazy" decoding="async" width="1400" height="976" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*DNW0ylu9LHLs4ztWVzw3UQ.png" /></p>

<p><a href="https://support.google.com/admanager/answer/13860694?hl=zh-Hant" target="_blank">https://support.google.com/admanager/answer/13860694?hl=zh-Hant</a></p>

<p>「 <a href="https://support.google.com/admanager/answer/13860694?hl=zh-Hant" target="_blank">Google Offerwall</a> 」は、個人的には「<strong>報酬型のOfferwall報酬広告</strong>」であり、報酬型広告の特性を組み合わせています。開発者は簡単に<strong>ウェブサイトのコンテンツページにアクセスするためにタスクの完了を指定でき</strong>、<strong>タスクはOfferwall報酬タスク</strong>となります。ユーザーは興味調査の完了、広告視聴、小額決済、ニュースレターの購読…または<a href="https://support.google.com/admanager/answer/13566866?hl=zh-Hant&amp;ref_topic=13821812&amp;sjid=14925592883586634734-NC" target="_blank">自社システムとのタスク連携</a>を設定できます。報酬内容はアクセス権で、数時間や数日の無制限アクセス、またはアクセス回数制限も可能です。そしてこれらはすべてGoogle Adsenseの動的広告コードを埋め込むだけで実現でき、自分でシステムを開発する必要はありません。</p>

<h4 id="-利点">✅ 利点</h4>

<ul>
  <li>
    <p><strong>実装が簡単</strong> ：サイトに <a href="https://support.google.com/adsense/answer/9189560?hl=zh-Hant" target="_blank">動的広告コードを埋め込む</a> だけで、一度設定すればずっと使えます。</p>
  </li>
  <li>
    <p><strong>直接収益</strong> ：Google Adsenseと同様の利点で、複雑な広告システムやデータ追跡システムを自分で構築する必要がありません。また、広告主を自分で探して広告を出稿する必要もなく、すべてプラットフォームが代わりに管理・運営します。</p>
  </li>
  <li>
    <p><strong>柔軟で多様</strong> ：より柔軟で多様なコンテンツやトラフィックの収益化方法を提供します。</p>
  </li>
  <li>
    <p><strong>クロスプラットフォーム</strong> ：スマホ版とPC版に対応。</p>
  </li>
</ul>

<h4 id="-欠点">❌ 欠点</h4>

<ul>
  <li>
    <p><strong>入札価格が低い</strong> ：これはGoogle Adsense全般の問題であり、広告の入札価格が低いです。</p>
  </li>
  <li>
    <p><strong>簡単にブロックされる</strong> ：Google Offerwallは純粋なフロントエンドで広告を表示するため、広告ブロッカーや開発者ツールを使うユーザーにより簡単に回避されます。<strong>そのため、重要で価値の高い敏感なコンテンツには導入をおすすめしません。</strong></p>
  </li>
</ul>

<h4 id="-技術要件">📝 技術要件</h4>

<ul>
  <li>
    <p>まずは <a href="https://adsense.google.com/" target="_blank">Google Adsense</a> に申請して承認を得る必要があります。<br />
<strong>現在はハードルが低くなっており、ウェブサイトのURLがあり、記事が5〜10本あれば基本的に申請は通ります。</strong></p>
  </li>
  <li>
    <p>サイトは HTML ヘッド内に<a href="https://support.google.com/adsense/answer/9189560?hl=zh-Hant" target="_blank">動的広告コード</a>を埋め込む必要があります。</p>
  </li>
</ul>

<h4 id="️-適したシーン">❤️ 適したシーン</h4>

<ul>
  <li>
    <p><strong>For 広告</strong> ：Google Adsense と同様に、自社広告枠を持たない中小規模のコンテンツサイトや個人ブログに適しています。例えば、<a href="https://wordpress.com/zh-tw/" target="_blank">Wordpress</a> や <a href="https://pages.github.com/" target="_blank">GitHub Pages</a> でホスティングされているサイトです。通常の広告枠表示に加え、価値のあるコンテンツ記事に対して Offerwall 報酬型広告を設定できます。<br />
<strong>本記事では For 広告を事例として扱い、現在は広告以外はまだベータ版です。</strong></p>
  </li>
  <li>
    <p><strong>アンケート、小額決済、ニュースレター登録用</strong>：どのウェブサイトでもこの仕組みを使って簡単にポップアップ広告を作成できます。</p>
  </li>
</ul>

<h3 id="インストールと有効化の手順">インストールと有効化の手順</h3>

<h4 id="動的広告コードの埋め込み">動的広告コードの埋め込み</h4>

<p>まず、サイトにGoogle Adsenseの広告コードが埋め込まれていることを確認してください。すでに動的広告を使用している場合は、この手順は省略できます。</p>

<p><strong><a href="https://adsense.google.com/" target="_blank">Google Adsense</a> にアクセス -&gt; 広告 -&gt; サイトをクリック -&gt; コードを取得：</strong></p>

<p><img src="/assets/ba132457e6a5/1*CYX4r932I3qkkOgKRVYTSg.webp" alt="" loading="lazy" decoding="async" width="1200" height="636" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjYzNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*CYX4r932I3qkkOgKRVYTSg.png" /></p>

<p><img src="/assets/ba132457e6a5/1*JAEN6wEMLaSgu5wpUkRTnw.webp" alt="" loading="lazy" decoding="async" width="1400" height="609" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjYwOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*JAEN6wEMLaSgu5wpUkRTnw.png" /></p>

<p>コードの内容をサイトの <code class="language-plaintext highlighter-rouge">&lt;head&gt;&lt;/head&gt;</code> タグ内に貼り付けてください：</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;head&gt;</span>
  //...
  <span class="nt">&lt;script</span> <span class="err">async</span> <span class="na">src=</span><span class="s">"https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3184248473087645"</span> <span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;/head&gt;</span>
</code></pre></div></div>

<h4 id="offerwall広告の作成">Offerwall広告の作成</h4>

<p><strong><a href="https://adsense.google.com/" target="_blank">Google Adsense</a> へ移動 -&gt; プライバシーとメッセージ -&gt; 管理 -&gt; メッセージを作成：</strong></p>

<p><img src="/assets/ba132457e6a5/1*aQ3svqP3lo16CGH8R-28yw.webp" alt="" loading="lazy" decoding="async" width="1200" height="1171" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjExNzEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/ba132457e6a5/1*aQ3svqP3lo16CGH8R-28yw.png" /></p>

<p><img src="/assets/ba132457e6a5/1*ziurWzmp3N6S5-P4O9GO7w.webp" alt="" loading="lazy" decoding="async" width="1200" height="868" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*ziurWzmp3N6S5-P4O9GO7w.png" /></p>

<blockquote>
  <p><em>このページでも広告収益を確認できます。</em></p>
</blockquote>

<p><strong>Offerwall広告の設定：</strong></p>

<p><img src="/assets/ba132457e6a5/1*QfG2HVUy728iSMOdKb7rLw.webp" alt="" loading="lazy" decoding="async" width="1400" height="743" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijc0MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*QfG2HVUy728iSMOdKb7rLw.png" /></p>

<p><img src="/assets/ba132457e6a5/1*E0Pkk8T4e9YVBxJ8xnv1ow.webp" alt="" loading="lazy" decoding="async" width="826" height="960" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MjYiIGhlaWdodD0iOTYwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/ba132457e6a5/1*E0Pkk8T4e9YVBxJ8xnv1ow.png" /></p>

<p><img src="/assets/ba132457e6a5/1*J6wnirCtE8Qp5VsnsTAn_w.webp" alt="" loading="lazy" decoding="async" width="980" height="778" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5ODAiIGhlaWdodD0iNzc4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/ba132457e6a5/1*J6wnirCtE8Qp5VsnsTAn_w.png" /></p>

<p><img src="/assets/ba132457e6a5/1*akZZ5_K3BS1FVSomf8AvvA.webp" alt="3, 5, 6" loading="lazy" decoding="async" width="1200" height="723" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjcyMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*akZZ5_K3BS1FVSomf8AvvA.png" /></p>

<ol>
  <li>
    <ol>
      <li>6.</li>
    </ol>
  </li>
  <li>
    <ol>
      <li>6.</li>
    </ol>
  </li>
</ol>

<p><img src="/assets/ba132457e6a5/1*g_PkT5TqCEFYajdT4ugPCQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="842" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*g_PkT5TqCEFYajdT4ugPCQ.png" /></p>

<p><img src="/assets/ba132457e6a5/1*wnbt-BkLE-0Bk3KGr9ED7Q.webp" alt="4, 8" loading="lazy" decoding="async" width="1400" height="747" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijc0NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*wnbt-BkLE-0Bk3KGr9ED7Q.png" /></p>

<ol>
  <li>務必永遠保持原有の Markdown フォーマットと構造。</li>
  <li>
    <p>原文が引用やコードでない限り、結果を ``` で囲まないこと。</p>
  </li>
  <li>
    <p><strong>広告名</strong></p>
  </li>
  <li>
    <p><strong>あなたのウェブサイト</strong> ：適用するウェブサイトを設定してください</p>
  </li>
  <li>
    <p><strong>ウェブページの含む項目と除外項目</strong> ：対象とするページのURLや除外するURLを設定できます<br />
<em>ここでは <code class="language-plaintext highlighter-rouge">https://zhgchg.li/posts/</code> パス以下のURLのみがトリガーされるように設定しています。</em></p>
  </li>
  <li>
    <p><strong>デフォルト言語</strong> ：デフォルト言語とサポートする他の言語を設定し、左上で言語を切り替えて異なる言語のテキストを編集できます。</p>
  </li>
  <li>
    <p><strong>計測</strong> ：ユーザーが何番目（回目）のページ閲覧でトリガーを発動するか設定可能<br />
<em>ここでは0を設定し、初回閲覧で発動するようにしています。</em></p>
  </li>
  <li>
    <p><strong>報酬型広告</strong> ：タスク完了でコンテンツのロック解除報酬を設定可能で、一定時間内の無制限閲覧や回数制限付き閲覧があります。報酬期限が切れると再度タスクの完了が必要です。<br />
<em>ここではタスクを1回完了すると24時間無制限で閲覧可能に設定しています。</em></p>
  </li>
  <li>
    <p><strong>コピー設定：</strong> コピー内容を指定し、ブランド力を高めるために少なくともロゴをアップロードしてください</p>
  </li>
  <li>
    <p><strong>スタイル設定：</strong> 7つのテキストをクリックすると、ここから文字スタイルや色を設定できます。<br />
<a href="https://support.google.com/admanager/answer/13860694?hl=zh-Hant#zippy=%2C%E5%A6%82%E4%BD%95%E6%B8%AC%E8%A9%A6-offerwall" target="_blank">テスト方法</a> を参考に、ページURLに <code class="language-plaintext highlighter-rouge">?fc=alwaysshow&amp;fctype=monetization</code> を追加して結果をプレビューしてください。</p>
  </li>
  <li><strong>変更を公開</strong> ：設定が完了したら必ず公開ボタンを押してください</li>
</ol>

<p><img src="/assets/ba132457e6a5/1*fRqD1tZ-513FjKsTTwDYkw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1047" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNDciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/ba132457e6a5/1*fRqD1tZ-513FjKsTTwDYkw.png" /></p>

<p>報酬完了後のメッセージは、現在変更できません。</p>

<p><img src="/assets/ba132457e6a5/1*fjfArCVeVNus7J48rEHcaQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="781" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc4MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*fjfArCVeVNus7J48rEHcaQ.png" /></p>

<p>広告が公開されていることを確認してください。</p>

<h4 id="offerwall広告のテスト">Offerwall広告のテスト</h4>

<p>シークレットブラウザを使用し、広告ブロックやトラッキング防止拡張機能が有効になっていないことを確認してから、ルール内のウェブページにアクセスしてください：</p>

<p><img src="/assets/ba132457e6a5/1*OSEzFBhd-wXSAdm-41aLjQ.webp" alt="https://zhgchg.li/posts/c008a9e8ceca/" loading="lazy" decoding="async" width="1400" height="1349" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEzNDkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/ba132457e6a5/1*OSEzFBhd-wXSAdm-41aLjQ.png" /></p>

<p><a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/">https://zhgchg.li/posts/c008a9e8ceca/</a></p>

<blockquote>
  <p>成功🙌🙌🙌</p>
</blockquote>

<p>できるだけChromeのシークレットモードでテストしてください。Safariでは広告ブロックやトラッキング防止をオフにする必要があり、少し面倒です。</p>

<h4 id="収益面">収益面</h4>

<p>私の閲覧数が多くないため、クリック単価もあまり高くなく、1回の広告クリックで約USD $0.01〜0.07程度です。</p>

<h3 id="mediumからgithub-pages-x-google-offerwallへ">MediumからGithub Pages x Google Offerwallへ</h3>

<p>以前の記事「<a href="/posts/zrealm-dev/mediumからgithub-pagesへ無痛転送-jekyllとchirpyで簡単サイト構築-a0c08d579ab1/">無痛で Medium から自分のサイトへ移行</a>」を参考に、まず Medium の記事を無痛で GitHub Pages にホスティングされた静的サイトへミラーリングし、その後サイトに Google Offerwall を追加することでコンテンツを収益化できます。</p>

<p>または直接「<a href="/posts/zrealm-life/medium-partner-program-全球対応で台湾も参加可能に-記事執筆で収益化を実現-cefdf4d41746/">Medium Partner Program 終於對全球(包含台灣)寫作者開放啦！</a>」を参考にして、Mediumの記事にペイウォールを追加し収益を得ることができます。</p>

<blockquote>
  <p><em>Mediumの有料壁機能は読者が月額料金を払って加入しなければ記事を読めないため、情報の伝達にはあまり親切ではないと感じています。だから私の記事は有料壁プランに参加していません。Google Offerwallはちょうどその中間を補完してくれます。ユーザーは広告を見るだけでコンテンツクリエイターを支援でき、月額料金の強制もなく、クリエイターも収益を得られる、一石二鳥です！</em></p>
</blockquote>

<h3 id="補足-offerwall報酬ウォール広告と報酬型広告の種類説明"><strong><em>[補足] Offerwall報酬ウォール広告と報酬型広告の種類説明</em></strong></h3>

<h4 id="offerwall--オファーウォール広告とは何ですか">Offerwall — オファーウォール広告とは何ですか？</h4>

<p>従来の固定枠広告と比べて、リワードウォール広告はユーザーとのインタラクションや目的性をより重視しています。コンテンツ表示、報酬インセンティブ、ユーザー行動を統合し、ユーザーは自発的に課金してコンテンツをアンロックするだけでなく、より楽しく参加型の方法で追加リソースを得ることができます。クリエイターはそこから追加収益を得られ、双方にとってウィンウィンの効果を実現します。</p>

<p><strong>例 — Line Points リワードウォール</strong></p>

<p><img src="/assets/ba132457e6a5/1*SWF8K0p5asGiDoPMhZRAWQ.webp" alt="" loading="lazy" decoding="async" width="554" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*SWF8K0p5asGiDoPMhZRAWQ.jpeg" /></p>

<p>日常生活の代表的な例は、Line Pointsです。ユーザーは直接Line Pointsを購入するだけでなく、Offerwall報酬画面から好きなミッション（友達追加、アカウント登録、アンケート回答、広告視聴など）を選んでクリアすると、対応する報酬を得られます。</p>

<h4 id="rewarded-ads--リワード広告">Rewarded Ads — <strong>リワード広告</strong></h4>

<p>獎励型広告は、ゲームやモバイルアプリでよく見られる広告形式で、ユーザーが自発的に特定の行動、例えば <strong>動画を視聴する、インタラクティブコンテンツをクリックする、または特定機能を試す</strong> といった行動を行うことで、仮想通貨や追加ライフ、ゲームアイテムなどの報酬を得られます。</p>

<p><strong>例 — キャンディークラッシュ</strong></p>

<p><img src="/assets/ba132457e6a5/1*D9PdoZg-mlCbtO19roltdQ.webp" alt="" loading="lazy" decoding="async" width="700" height="1400" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiIGhlaWdodD0iMTQwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/ba132457e6a5/1*D9PdoZg-mlCbtO19roltdQ.png" /></p>

<p>クラシックな例としては、ゲーム内で死亡後に続けて遊べる広告があります。このような広告はユーザーの参加度と満足度を高めるだけでなく、ユーザー体験を損なうことなく開発者が収益を得られるため、双方にとって利益となります。</p>

<p><em><a href="https://medium.com/zrealm-ios-dev/google-offerwall-%E5%BB%A3%E5%91%8A-%E5%85%A7%E5%AE%B9%E5%89%B5%E4%BD%9C%E8%80%85%E7%9A%84%E5%85%A8%E6%96%B0%E6%94%B6%E7%9B%8A%E9%81%B8%E6%93%87-ba132457e6a5" target="_blank">Post</a> は Medium から <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a> によって変換されました。</em></p>]]></content>
  </entry><entry>
    <title type="html">Google Apps Script Web App｜GitHub Actions連携で無料CI/CD打包ツール構築｜跨團隊共有を実現</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-dev/google-apps-script-web-app-github-actions%E9%80%A3%E6%90%BA%E3%81%A7%E7%84%A1%E6%96%99ci-cd%E6%89%93%E5%8C%85%E3%83%84%E3%83%BC%E3%83%AB%E6%A7%8B%E7%AF%89-%E8%B7%A8%E5%9C%98%E9%9A%8A%E5%85%B1%E6%9C%89%E3%82%92%E5%AE%9F%E7%8F%BE-4273e57e7148/" rel="alternate" type="text/html" title="Google Apps Script Web App｜GitHub Actions連携で無料CI/CD打包ツール構築｜跨團隊共有を実現" />
    <published>2025-07-10T20:30:51+08:00</published>
    <updated>2025-11-19T23:59:42+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-dev/4273e57e7148</id><summary type="html">開発チーム向けにGAS Web AppでGitHub、Slack、Firebase、Asana/Jira APIを連携し、中継プラットフォームを構築。打包作業を自動化し、効率的なCI/CD環境を無料で実現します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm Dev." /><category term="iosアプリ開発" /><category term="ci-cd" /><category term="google-apps-script" /><category term="ウェブ開発" /><category term="ツール" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/4273e57e7148/1*kJhD4PCaIphZ9G1BG_dtNw.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-dev/google-apps-script-web-app-github-actions%E9%80%A3%E6%90%BA%E3%81%A7%E7%84%A1%E6%96%99ci-cd%E6%89%93%E5%8C%85%E3%83%84%E3%83%BC%E3%83%AB%E6%A7%8B%E7%AF%89-%E8%B7%A8%E5%9C%98%E9%9A%8A%E5%85%B1%E6%9C%89%E3%82%92%E5%AE%9F%E7%8F%BE-4273e57e7148/"><![CDATA[<h3 id="cicd-実践ガイド4google-apps-script-web-app-を使って-github-actions-と連携し無料で使いやすいパッケージングツールプラットフォームを構築する">CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</h3>

<p>GAS Web App で GitHub、Slack、Firebase または Asana/Jira API と連携し、中継ステーションを構築して、チーム間で共有できるパッケージングツールプラットフォームを提供</p>

<p><img src="/assets/4273e57e7148/1*kJhD4PCaIphZ9G1BG_dtNw.webp" alt="Photo by Lee Campbell" loading="lazy" decoding="async" width="1200" height="801" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4273e57e7148/1*kJhD4PCaIphZ9G1BG_dtNw.jpeg" /></p>

<p>Photo by <a href="https://unsplash.com/@leecampbell?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash" target="_blank">Lee Campbell</a></p>

<h3 id="はじめに">はじめに</h3>

<p>前回の「<a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/"><strong>CI/CD 実践ガイド（三）：GitHub Actions を使った App iOS CI と CD ワークフローの実装</strong></a>」では、App iOS プロジェクトの CI/CD 基盤機能を完成させ、自動テスト検証とパッケージング・デプロイができるようになりました。しかし、実際の製品開発プロセスでは、<strong>パッケージング・デプロイ作業は主に他の職能パートナーに引き渡して</strong> QA（品質保証）機能の検証を行うためのものです。この場合、CD のシナリオはエンジニアリング部門だけに限らず、QA、PM、デザイン（Design QA）、さらには経営者が先に試したい場合もあります。</p>

<p>GitHub Actions の <code class="language-plaintext highlighter-rouge">workflow_dispatch</code> 手動フォームトリガーは、簡単なフォームでユーザーがビルド操作を行えますが、対象が非エンジニアの場合は非常に使いにくいです。彼らは「ブランチとは何か？」「フィールドは入力すべきか？」「ビルドが完了したかどうかはどう確認するのか？」「完了したらどうやってダウンロードするのか？」などが分かりません。</p>

<p>また、権限管理の問題もあります。別の職能のメンバーに直接 GitHub Actions でビルドを使わせるには、そのメンバーのアカウントをリポジトリに追加する必要があり、<strong>セキュリティ管理上非常に危険かつ不合理</strong>です。ビルドフォームを操作するだけなのに、ソースコード全体を見せる必要があるのです。</p>

<p>Jenkinsは独立したWebツールプラットフォームがありますが、GitHub Actionsにはこの機能しかありません。</p>

<p><img src="/assets/4273e57e7148/1*qDD8HAAHxDxPEU3vJPEhjA.webp" alt="`workflow_dispatch のフォームスタイル`" loading="lazy" decoding="async" width="342" height="445" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNDIiIGhlaWdodD0iNDQ1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*qDD8HAAHxDxPEU3vJPEhjA.png" /></p>

<p><code class="language-plaintext highlighter-rouge">workflow_dispatch のフォームスタイル</code></p>

<p>したがって、<strong>他の職能ユーザー向けにサービスを提供する中継パッケージプラットフォームが必要です</strong>。AsanaやJiraのタスクを統合し、ユーザーがタスクから直接アプリをパッケージングでき、進捗確認やパッケージ結果のダウンロードもその場で行えます。</p>

<p><img src="/assets/4273e57e7148/1*bHYawmSnhqwB4TzIJVfGow.webp" alt="GAS Web App 中継サーバー" loading="lazy" decoding="async" width="1400" height="1037" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMzciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/4273e57e7148/1*bHYawmSnhqwB4TzIJVfGow.png" /></p>

<p>GAS Web App 中継ステーション</p>

<p><a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/">上一篇</a> は右側のコアである GitHub Actions CI/CD ワークフローの開発に焦点を当てています；この記事は左側のエンドユーザー向けパッケージングツールプラットフォームとユーザー体験の向上に注目しています。</p>

<h4 id="google-apps-script--web-app-パッケージングツールプラットフォーム-成果図">Google Apps Script — Web App パッケージングツールプラットフォーム 成果図</h4>

<p><img src="/assets/4273e57e7148/1*yXMeaOELhqdvMCxIJ5ElBw.gif" alt="" loading="lazy" decoding="async" width="1048" height="822" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDQ4IiBoZWlnaHQ9IjgyMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<p><img src="/assets/4273e57e7148/1*EM0goWpuDeHGVkZoybLm8g.webp" alt="" loading="lazy" decoding="async" width="980" height="899" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5ODAiIGhlaWdodD0iODk5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*EM0goWpuDeHGVkZoybLm8g.png" /></p>

<p><img src="/assets/4273e57e7148/1*haoGMvAUroz7rUMDEez9gA.webp" alt="" loading="lazy" decoding="async" width="984" height="826" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5ODQiIGhlaWdodD0iODI2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*haoGMvAUroz7rUMDEez9gA.png" /></p>

<p><img src="/assets/4273e57e7148/1*afCwKITlerG1g6swB_2wZA.webp" alt="" loading="lazy" decoding="async" width="955" height="758" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTUiIGhlaWdodD0iNzU4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*afCwKITlerG1g6swB_2wZA.png" /></p>

<p><img src="/assets/4273e57e7148/1*mvwpHBdrC73_PjL8H32nkw.webp" alt="" loading="lazy" decoding="async" width="554" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4273e57e7148/1*mvwpHBdrC73_PjL8H32nkw.jpeg" /></p>

<p><img src="/assets/4273e57e7148/1*BbbEd_thhUOdbAQqsCt-Tw.webp" alt="" loading="lazy" decoding="async" width="1046" height="585" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDQ2IiBoZWlnaHQ9IjU4NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4273e57e7148/1*BbbEd_thhUOdbAQqsCt-Tw.png" /></p>

<p><img src="/assets/4273e57e7148/1*HXjfMpUPssaw3sJgH6KKJQ.webp" alt="" loading="lazy" decoding="async" width="312" height="292" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMTIiIGhlaWdodD0iMjkyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*HXjfMpUPssaw3sJgH6KKJQ.png" /></p>

<ul>
  <li>
    <p><strong>パッキングフォーム：</strong> プロジェクト管理ツールからチケット番号を取得し、GitHubからオープン中のプルリクエストを取得する統合機能</p>
  </li>
  <li>
    <p><strong>ビルド記録：</strong> ビルド履歴の表示、進行中のビルドタスクの進捗状況、クリックして Firebase App Distribution のダウンロードリンクを取得、情報表示</p>
  </li>
  <li>
    <p><strong>Runner 状態：</strong> Self-hosted Runner の状態を表示します。</p>
  </li>
  <li>
    <p><strong>Slack ビルド進捗通知。</strong></p>
  </li>
  <li>
    <p>モバイル対応</p>
  </li>
  <li>
    <p>組織チーム内のアカウント使用制限をサポート</p>
  </li>
</ul>

<p><strong>主な職務内容</strong></p>

<p>0 ステータス、0 データベース、<strong>純粋に中継交換ステーションとして</strong>、各種 API のデータを統合表示 (例: Asana/Jira/GitHub)、フォームリクエストを GitHub Actions に転送。</p>

<p><strong>操作要件：</strong> スマホとパソコンに対応。</p>

<p><strong>権限要件：</strong> チーム組織のメンバーのみがアクセス可能に制限できること。</p>

<h4 id="オンラインデモ-web-アプリ"><a href="https://script.google.com/macros/s/AKfycbwNW6N5ozKbIz_E1HK6yFEUtA8KQrUciS-jcPsQptvIKlARmKgLxbQzNu8ksVeg-BmEfg/exec" target="_blank">オンラインデモ Web アプリ</a></h4>

<ul>
  <li>初めてご利用の場合は、以下の図を参考に権限を付与してください（デモアプリ専用）：</li>
</ul>

<p><img src="/assets/4273e57e7148/0*7pJ876yQbcakQvdO.webp" alt="" loading="lazy" decoding="async" width="700" height="607" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiIGhlaWdodD0iNjA3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/0*7pJ876yQbcakQvdO.png" /></p>

<p>プロジェクトのソースコード： <a href="https://script.google.com/home/projects/1CBB39OMedqP9Ro1WSlvgDnMBin4-ksyhgly2h_KrbOuFiPHTalNgwHOp/edit" target="_blank">https://script.google.com/home/projects/1CBB39OMedqP9Ro1WSlvgDnMBin4-ksyhgly2h_KrbOuFiPHTalNgwHOp/edit</a></p>

<h3 id="技術選択">技術選択</h3>

<p><a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/">第一篇記事</a> で触れましたが、ここで改めて詳しくまとめます。</p>

<h4 id="slack-との統合">Slack との統合</h4>

<p>私たちは Slack をパッケージングプラットフォームとして使い、自前でバックエンドサービスを開発し GCP に構築しました。Slack API や Asana API と連携し、Slack から送られてきたフォームを GitHub API に転送して GitHub Actions をトリガーする仕組みです。使用感は非常に良く、チームの協業ツール上で統一されているため、ストレスなく使えました。<strong>しかし欠点は開発およびその後の保守コストが非常に高いことです。</strong> Ktor で開発したバックエンドサービスのため、アプリエンジニアがバックエンドも兼務し、Google サービスの OAuth 統合問題を処理しなければならず、一部機能（例：審査送信）もここで実装するなど複雑でした。後から入ったメンバーがうまく引き継げなければほぼ保守不可能になり、さらに毎月 $15 USD の GCP サーバー費用もかかりました。</p>

<p>初期は Cloud Functions などの FaaS サービスを使って Slack API と連携しようとしましたが、Slack API は3秒以内に応答しないと失敗とみなされます。FaaS は <a href="https://www.cloudflare.com/zh-tw/learning/serverless/what-is-serverless/" target="_blank">コールドスタート問題</a> があり、一定時間呼び出されないと休止状態になり、再度呼び出すと応答に時間がかかる（≥5秒）ため、Slack のパッケージフォームが不安定で、タイムアウトエラーが頻発しました。</p>

<h4 id="社内システムへの統合">社内システムへの統合</h4>

<p>もちろんこれは最適解ですが、チームにWebやバックエンドの人員がいる場合は、既存のシステムと直接統合するのが最も良く、かつ安全です。</p>

<blockquote>
  <p><em>この記事の前提は：なし、アプリは自立自強です。</em></p>
</blockquote>

<h4 id="google-apps-script--web-アプリ">Google Apps Script — Web アプリ</h4>

<p>Google Apps Script は私たちの古くからのパートナーで、これまで多くのRPAプロジェクトでスケジュールトリガーによるタスク実行に使ってきました。例えば、「<a href="/posts/zrealm-ロボティック-プロセス-オートメーション/crashlyticsとgoogle-analytics連携-appのcrash-free-users率を自動取得する方法-793cb8f89b72/">Crashlytics + Google Analytics 自動で App Crash-Free Users Rate を取得</a>」や「<a href="/posts/zrealm-ロボティックプロセスオートメーション/google-apps-scriptで毎日データ報告をrpa自動化-効率化と正確性向上の秘訣-f6713ba3fee3/">Google Apps Script を使った毎日データレポートのRPA自動化</a>」などです。この時、GASの機能の一つであるWeb（App）としてデプロイして直接ウェブサービスとして使えることを思い出しました。</p>

<p><strong>Google Apps Script の利点：</strong></p>

<ul>
  <li>
    <p>✅ 無料で、<a href="https://developers.google.com/apps-script/guides/services/quotas?hl=zh-tw" target="_blank">通常の利用ではほぼ制限を感じない</a></p>
  </li>
  <li>
    <p>✅ Functions as a Service（FaaS）方式で、サーバーの構築や運用管理が不要</p>
  </li>
  <li>
    <p>✅ 権限管理は Google Workspace と同様で、組織内の Google アカウントだけを使用可能に設定できる</p>
  </li>
  <li>
    <p>✅ Google エコシステム関連サービス（例：Firebase、GA など）とデータをスムーズに統合可能（OAuth を自分で実装する必要なし）</p>
  </li>
  <li>
    <p>✅ プログラミング言語は JavaScript で、習得が容易（V8 Runtime は ES6+ をサポート）</p>
  </li>
  <li>
    <p>✅ すばやく作成し、すばやく公開、すばやく利用可能</p>
  </li>
  <li>
    <p>✅ サービスは安定しており、長期間の運用実績（16年以上）がある</p>
  </li>
  <li>
    <p><strong>✅ AIが支援！ChatGPTを活用した開発で、正確率95％を実証</strong></p>
  </li>
</ul>

<p><strong>Google Apps Script の欠点：</strong></p>

<ul>
  <li>
    <p>❌ 内蔵のバージョン管理は一言で説明できません</p>
  </li>
  <li>
    <p>❌ ファイル、データ保存、キー／証明書管理は標準でサポートされていません</p>
  </li>
  <li>
    <p>❌ Web App は100%レスポンシブデザイン（RWD）を実現できません</p>
  </li>
  <li>
    <p>❌ プロジェクトは個人アカウントにのみ紐付けられ、組織にはできません</p>
  </li>
  <li>
    <p>❌ Google は継続的に開発・保守していますが、全体の機能更新は遅いです</p>
  </li>
  <li>
    <p>❌ ネットワークリクエスト <code class="language-plaintext highlighter-rouge">UrlFetchApp</code> は User-Agent の設定をサポートしていません</p>
  </li>
  <li>
    <p>❌ Web App の <code class="language-plaintext highlighter-rouge">doGet</code> / <code class="language-plaintext highlighter-rouge">doPost</code> では Headers 情報の取得がサポートされていません</p>
  </li>
  <li>
    <p>❌ FaaS の<a href="https://www.cloudflare.com/zh-tw/learning/serverless/what-is-serverless/" target="_blank">コールドスタート問題</a></p>
  </li>
  <li>
    <p>❌ <strong>複数人の同時開発はサポートされていません</strong><br />
しかし、Web App ではあまり影響がなく、せいぜい数秒待ってからページに入るだけです。</p>
  </li>
</ul>

<p>以上は GAS 自体のサービスの長所と短所ですが、パッケージングツールの Web に与える影響は大きくありません。この方法を Slack 方案と比較すると、より速く、軽量で、引き継ぎやすいという利点があります。<strong>欠点はチームがこのツールの URL と使い方を把握する必要があること、そして GAS のライブラリ機能が限られていること</strong>（例：組み込みの暗号化アルゴリズムライブラリがない）ため、基本的に純粋な中継プラットフォームしか作れません。例えば審査送信の場合も、審査リクエストを GitHub Actions に転送するだけになります。</p>

<blockquote>
  <p><strong><em>また、Google Workspace の作業環境を利用しているチームにのみ適用されます。</em></strong> <em>リソースとニーズを考慮した結果、Google Apps Script — Web App を使ってパッケージングツールプラットフォームを実現しました。</em></p>
</blockquote>

<h4 id="uiフレームワーク">UIフレームワーク</h4>

<p><a href="https://getbootstrap.com/" target="_blank"><img src="https://getbootstrap.com/docs/5.3/assets/brand/bootstrap-social.png" alt="" /></a></p>

<p>直接 Bootstrap CDN を使用します。自分で CSS スタイルを作るのは面倒なので、Bootstrap を AI にどう組み合わせて使うか聞くほうが正確で便利です。</p>

<h3 id="実践してみよう">実践してみよう</h3>

<p>こちらでプラットフォームの全体構成をオープンソース化しました。各チームは自分たちのニーズに合わせてこのバージョンをカスタマイズしてください。</p>

<h4 id="オープンソースサンプルプロジェクト">オープンソースサンプルプロジェクト</h4>

<p>GAS 上で直接プロジェクトを表示：</p>

<p><a href="https://script.google.com/home/projects/1CBB39OMedqP9Ro1WSlvgDnMBin4-ksyhgly2h_KrbOuFiPHTalNgwHOp/edit" target="_blank"><img src="https://www.gstatic.com/devrel-devsite/prod/v78ce60439c72b9da3632137223a86ae38b78a872a1f6dee1b5c1c8cfa57fe81d/developers/images/opengraph/white.png" alt="" /></a></p>

<p><img src="/assets/4273e57e7148/1*Xzh2eBpVR92uZq-8POPegw.webp" alt="" loading="lazy" decoding="async" width="760" height="860" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjAiIGhlaWdodD0iODYwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*Xzh2eBpVR92uZq-8POPegw.png" /></p>

<p>GitHub リポジトリのバックアップ：</p>

<p><a href="https://github.com/ZhgChgLi/google-apps-script-cd-web-app-demo" target="_blank"><img src="https://opengraph.githubassets.com/3d7c517cd747bc49656701ef275357816667a72ebe2b7744c22e8a34c82b4a26/ZhgChgLi/google-apps-script-cd-web-app-demo" alt="" /></a></p>

<h4 id="ファイル構成">ファイル構成</h4>

<p><img src="/assets/4273e57e7148/1*ohVakhlaflRXCI_3j2-cOA.webp" alt="" loading="lazy" decoding="async" width="227" height="716" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMjciIGhlaWdodD0iNzE2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*ohVakhlaflRXCI_3j2-cOA.png" /></p>

<p><img src="/assets/4273e57e7148/1*AyIEF0wqEFdMDBuRzQXDEQ.webp" alt="" loading="lazy" decoding="async" width="1177" height="991" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTc3IiBoZWlnaHQ9Ijk5MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4273e57e7148/1*AyIEF0wqEFdMDBuRzQXDEQ.png" /></p>

<p>とてもシンプルなクラスベースのMVC風アーキテクチャを作成しました。調整したい場合や機能がわからないときは、AIに質問すれば正確な答えが得られます。</p>

<p><strong>システム</strong></p>

<ul>
  <li>
    <p>appsscript.json: GAS システムのメタデータ設定ファイル<br />
<strong>重要なのは「oauthScopes」変数で、このスクリプトが使用する外部権限を宣言します。</strong></p>
  </li>
  <li>
    <p>Entrypoint.gs: doGet() エントリーポイントを定義</p>
  </li>
</ul>

<p><strong>コントローラー</strong></p>

<ul>
  <li>Controller_iOS.gs: iOSパッケージツールページのコントローラーで、Viewに表示するデータを取得する役割を担います。</li>
</ul>

<p><strong>ビュー</strong></p>

<ul>
  <li>
    <p>View_index.html: パッケージングツールの全体構造とホームページ</p>
  </li>
  <li>
    <p>View_iOS.html: iOS パッケージツールページの骨組み</p>
  </li>
  <li>
    <p>View_iOS_Runs.html: iOS ビルドツール — ビルド履歴詳細ページ</p>
  </li>
  <li>
    <p>View_iOS_Form.html: iOS パッケージツール — パッケージフォームページ</p>
  </li>
  <li>
    <p>View_iOS_Runners.html: iOS ビルドツール — Self-hosted Runner ステータスページ</p>
  </li>
</ul>

<p><strong>Model(Lib)</strong></p>

<ul>
  <li>
    <p>Credentials.gs: キー内容の定義<br />
(⚠️️️ご注意ください️、GASでGCP IAMを使うのは非常に複雑なため、ここで直接キーを定義しています。<strong>そのため、このGASプロジェクトには機密情報が含まれているので、プロジェクトの閲覧・編集権限を安易に共有しないでください</strong> )</p>
  </li>
  <li>
    <p>StubData.gs: オンラインデモ用のスタブメソッドとデータ。</p>
  </li>
  <li>
    <p>Settings.gs: 一部のよく使う設定と lib の初期化。</p>
  </li>
  <li>
    <p>GitHub.gs: GitHub API 操作のラッパー。</p>
  </li>
  <li>
    <p>Slack.gs: Slack API 操作のラッパー。</p>
  </li>
  <li>
    <p>Firebase.gs: Firebase — App Distribution API 操作のラッパー。</p>
  </li>
</ul>

<h4 id="自分のパッケージングプラットフォームを作成する">自分のパッケージングプラットフォームを作成する</h4>

<ol>
  <li><a href="https://script.google.com/home" target="_blank">Google Apps Script プロジェクト</a> を作成し、名前を付ける</li>
</ol>

<p><img src="/assets/4273e57e7148/1*_uVqy6cDNvFSEL0feOS-pw.webp" alt="" loading="lazy" decoding="async" width="919" height="369" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTkiIGhlaWdodD0iMzY5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*_uVqy6cDNvFSEL0feOS-pw.png" /></p>

<p>プロジェクト設定に移動し、「エディタで『appsscript.json』マニフェストファイルを表示する」にチェックを入れると、「appsscript.json」メタデータファイルが表示されます。</p>

<p><img src="/assets/4273e57e7148/1*tvXsQufQs5-5UzV0bg5WLA.webp" alt="" loading="lazy" decoding="async" width="736" height="466" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MzYiIGhlaWdodD0iNDY2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*tvXsQufQs5-5UzV0bg5WLA.png" /></p>

<ol>
  <li>私の<a href="https://script.google.com/home/projects/1CBB39OMedqP9Ro1WSlvgDnMBin4-ksyhgly2h_KrbOuFiPHTalNgwHOp/edit" target="_blank">オープンソースプロジェクトファイル</a>を参考に、すべてのファイルをサンプル通りに作成し、内容をそのままコピーしてください。</li>
</ol>

<p><img src="/assets/4273e57e7148/1*PxZvHNeW6PFaaqmZqifFfg.webp" alt="" loading="lazy" decoding="async" width="572" height="272" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NzIiIGhlaWdodD0iMjcyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*PxZvHNeW6PFaaqmZqifFfg.png" /></p>

<blockquote>
  <p><strong><em>馬鹿だけど、仕方がない。</em></strong></p>
</blockquote>

<blockquote>
  <p><em>まず StubData.gs をコピーしてください。初回デプロイのテストに使用できます。</em></p>
</blockquote>

<blockquote>
  <p><em>もう一つの方法は、<a href="https://developers.google.com/apps-script/guides/clasp?hl=zh-tw" target="_blank">clasp (Google Apps Script CLI)</a> を使ってデモプロジェクトをgit cloneし、その後コードをプッシュすることです。</em></p>
</blockquote>

<p><img src="/assets/4273e57e7148/1*FLM2SGIhAI7Z7OWIJpeT9A.webp" alt="" loading="lazy" decoding="async" width="1150" height="852" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTUwIiBoZWlnaHQ9Ijg1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4273e57e7148/1*FLM2SGIhAI7Z7OWIJpeT9A.png" /></p>

<p>コピーすると、サンプルプロジェクトと全く同じになります。</p>

<ol>
  <li>初回デプロイ「ウェブアプリケーション」で結果を確認する</li>
</ol>

<p><img src="/assets/4273e57e7148/1*KbWpaEinVZh6M8o8bCCl6A.webp" alt="" loading="lazy" decoding="async" width="833" height="239" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzMiIGhlaWdodD0iMjM5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*KbWpaEinVZh6M8o8bCCl6A.png" /></p>

<p><img src="/assets/4273e57e7148/1*2RrwNxZVidodX6Kq037Yvw.webp" alt="" loading="lazy" decoding="async" width="761" height="601" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjEiIGhlaWdodD0iNjAxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*2RrwNxZVidodX6Kq037Yvw.png" /></p>

<p><img src="/assets/4273e57e7148/1*CZSIfASW4hmQeXwTS3x7Fg.webp" alt="" loading="lazy" decoding="async" width="761" height="602" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjEiIGhlaWdodD0iNjAyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*CZSIfASW4hmQeXwTS3x7Fg.png" /></p>

<p>プロジェクト右上の「デプロイ」→「新しいデプロイ」→ タイプ「ウェブアプリケーション」:</p>

<p><strong>実行権限：</strong></p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">統一はあなたのアカウントでスクリプトを実行します。</code></p>
  </li>
  <li>
    <p>Webアプリにアクセスするユーザーは、現在ログインしているGoogleアカウントのユーザーとしてスクリプトを実行します。</p>
  </li>
</ul>

<p><strong>誰がアクセスできますか：</strong></p>

<ul>
  <li>
    <p>私だけです</p>
  </li>
  <li>
    <p><strong>XXX 同じ組織内のすべてのユーザー</strong> <code class="language-plaintext highlighter-rouge">同じ組織かつログイン済みのGoogleアカウントユーザーのみアクセス可能。</code></p>
  </li>
  <li>
    <p>ログインしているすべての Google アカウントのユーザー <code class="language-plaintext highlighter-rouge">ログインしている Google アカウントのユーザーは誰でもアクセス可能です。</code></p>
  </li>
  <li>
    <p>全員が <code class="language-plaintext highlighter-rouge">Googleアカウントにログインする必要はなく、誰でも公開アクセス可能です。</code></p>
  </li>
</ul>

<blockquote>
  <p><em>内部ツールの場合：「<strong>誰がアクセス可能か：XXX 同じ組織内のすべてのユーザー」＋「実行者の身分：ウェブアプリにアクセスしているユーザー」を選択してセキュリティ管理を行うことができます。</strong></em></p>
</blockquote>

<p>デプロイ完了後の「ウェブアプリケーション」URLが、あなたの Web App パッケージツールのURLになります。チームメンバーと共有して使えます。（URLは見た目が悪いので、短縮URLサービスで加工しても良いです。<strong>デプロイ内容を更新してもURLは変わりません</strong>）</p>

<h4 id="ユーザーが初めて使用する際に同意が必要">ユーザーが初めて使用する際に同意が必要</h4>

<p>初めて Web App のURLをクリックすると、まず認証の許可が必要です。</p>

<p><img src="/assets/4273e57e7148/1*lckRkGtc7EVqz9aTZaBIOw.webp" alt="" loading="lazy" decoding="async" width="519" height="491" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTkiIGhlaWdodD0iNDkxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*lckRkGtc7EVqz9aTZaBIOw.png" /></p>

<p><img src="/assets/4273e57e7148/1*l1t290T_4xs1ly-RjjZXtg.webp" alt="" loading="lazy" decoding="async" width="766" height="674" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjYiIGhlaWdodD0iNjc0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*l1t290T_4xs1ly-RjjZXtg.png" /></p>

<p><img src="/assets/4273e57e7148/1*O9ItCSBNoBcuqepd-6ygCA.webp" alt="" loading="lazy" decoding="async" width="722" height="630" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MjIiIGhlaWdodD0iNjMwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*O9ItCSBNoBcuqepd-6ygCA.png" /></p>

<ul>
  <li>
    <p>Review Permission → この Web App を使用するアカウントの身分を選択してください</p>
  </li>
  <li>
    <p>未検証の警告ウィンドウで、「詳細設定」をクリックして展開 → 「XXX」へ移動（安全ではありません）をクリック</p>
  </li>
</ul>

<p><img src="/assets/4273e57e7148/1*cYloLsBROLbZDPIciYUm5g.webp" alt="" loading="lazy" decoding="async" width="1054" height="876" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDU0IiBoZWlnaHQ9Ijg3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4273e57e7148/1*cYloLsBROLbZDPIciYUm5g.png" /></p>

<ul>
  <li>「許可する」をクリックしてください</li>
</ul>

<blockquote>
  <p><em>今後スクリプトの権限が変更されない限り、再認証は不要です。</em></p>
</blockquote>

<p><strong>認証同意が完了すると、パッケージングツールのホームページに移動します：</strong></p>

<p><img src="/assets/4273e57e7148/1*vG5SsVFHPPDukc4ej0hqLA.webp" alt="" loading="lazy" decoding="async" width="1149" height="1113" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQ5IiBoZWlnaHQ9IjExMTMiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/4273e57e7148/1*vG5SsVFHPPDukc4ej0hqLA.png" /></p>

<blockquote>
  <p>Demo パッケージツールのデプロイ成功 🎉🎉🎉</p>
</blockquote>

<p>注：「このアプリケーションは Google Apps Script のユーザーによって作成されました」というメッセージは自動で非表示にできません。</p>

<h4 id="デプロイの更新">デプロイの更新</h4>

<blockquote>
  <p>⚠️すべてのコード変更は、デプロイの更新が必要です。</p>
</blockquote>

<blockquote>
  <p>️️⚠️すべてのコード変更は、デプロイの更新を行わないと反映されません。</p>
</blockquote>

<blockquote>
  <p>⚠️すべてのコード変更は、デプロイの更新が必要です。</p>
</blockquote>

<p>ここで注意すべきは、コードの変更を保存してもすぐに Web App に反映されないことです。そのため、リロードしても変化がない場合はこの理由によります。<strong>「デプロイ」→「デプロイの管理」→「編集」→ バージョン「新しいバージョンを作成」→「デプロイ」→「完了」</strong> の操作が必要です。</p>

<p><img src="/assets/4273e57e7148/1*VsfCEfwnPlx9RbQ8DtXpnA.webp" alt="" loading="lazy" decoding="async" width="298" height="229" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOTgiIGhlaWdodD0iMjI5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*VsfCEfwnPlx9RbQ8DtXpnA.png" /></p>

<p><img src="/assets/4273e57e7148/1*n62MVd6o8W3hUtQpfn9Q0w.webp" alt="" loading="lazy" decoding="async" width="761" height="603" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjEiIGhlaWdodD0iNjAzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*n62MVd6o8W3hUtQpfn9Q0w.png" /></p>

<blockquote>
  <p><em>デプロイ後にページをリロードすると変更が反映されます。</em></p>
</blockquote>

<h4 id="テストデプロイを追加して開発を便利にする">テストデプロイを追加して開発を便利にする</h4>

<p><img src="/assets/4273e57e7148/1*4fLoW6jf8z1AIXvULW-AOA.webp" alt="" loading="lazy" decoding="async" width="413" height="235" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MTMiIGhlaWdodD0iMjM1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*4fLoW6jf8z1AIXvULW-AOA.png" /></p>

<p><img src="/assets/4273e57e7148/1*yvTxeaImQ4Mr7FwESsuf5A.webp" alt="" loading="lazy" decoding="async" width="761" height="599" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjEiIGhlaWdodD0iNTk5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*yvTxeaImQ4Mr7FwESsuf5A.png" /></p>

<p>前述の通り、すべての変更を反映させるにはデプロイの更新が必要です。これは開発段階では非常に面倒なので、開発中は「テストデプロイ」を使って変更が正しいか素早く検証できます。</p>

<p><strong>「デプロイ」→「テストデプロイ作業」→ テスト用「ウェブアプリケーション」URLを取得。</strong></p>

<p><img src="/assets/4273e57e7148/1*Rt0XEw9uAev58isLEnsoPA.webp" alt="" loading="lazy" decoding="async" width="762" height="603" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjIiIGhlaWdodD0iNjAzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*Rt0XEw9uAev58isLEnsoPA.png" /></p>

<p>開発段階では、このURLを直接使用して保存できます。ファイルの変更を保存したら、この開発用URLに戻ってページをリロードすると成果が確認できます！</p>

<blockquote>
  <p><strong><em>すべての開発が完了したら、前述の手順に従って更新・デプロイし、ユーザーにリリースします。</em></strong></p>
</blockquote>

<h3 id="demoサンプルプロジェクトを実際のデータに接続する方法">Demoサンプルプロジェクトを実際のデータに接続する方法</h3>

<p>次に本題ですが、実際のデータと連携するため、GitHub Actions Workflow は<a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/"><strong>前回の記事で作成した CI/CD フロー</strong></a>を参照しています。実際の Actions Workflow に合わせてパラメータを調整してください。</p>

<h4 id="️修正前にご注意ください">⚠️修正前にご注意ください</h4>

<p>Google Apps Script プラットフォームは複数人や複数ウィンドウでの開発をあまりサポートしていません。私が経験した問題は、誤って編集ウィンドウを2つ開き、Aで編集した後にBで編集したため、変更がBの古いバージョンで上書きされてしまったことです。したがって、<strong>同時に一人一つのウィンドウだけでスクリプトを編集することを推奨します</strong>。</p>

<h4 id="github-連携">GitHub 連携</h4>

<p><strong>GitHub API トークンの入力：</strong></p>

<p>GitHub -&gt; アカウント -&gt; 設定 -&gt; 開発者設定 -&gt; 詳細設定パーソナルアクセストークン または パーソナルアクセストークン（クラシック）。</p>

<p>Fine-grained personal access tokens の使用を推奨します（より安全ですが、有効期限があります）。</p>

<p><strong>Fine-grained personal access tokens に必要な権限は以下の通りです：</strong></p>

<p><img src="/assets/4273e57e7148/1*lCNQHwC4EMU4gNXYC-zs2A.webp" alt="" loading="lazy" decoding="async" width="821" height="579" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MjEiIGhlaWdodD0iNTc5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*lCNQHwC4EMU4gNXYC-zs2A.png" /></p>

<ul>
  <li>
    <p>Repo: 操作するリポジトリを選択してください</p>
  </li>
  <li>
    <p>権限: <code class="language-plaintext highlighter-rouge">Actions (読み取り/書き込み)</code> 、 <code class="language-plaintext highlighter-rouge">Administration (読み取り専用)</code></p>
  </li>
</ul>

<blockquote>
  <p><em>特定のアカウントに依存したくない場合は、クリーンなチーム用の GitHub アカウントを作成し、そのトークンを使用することをおすすめします。</em></p>
</blockquote>

<p>GAS プロジェクト → <code class="language-plaintext highlighter-rouge">Credentials.gs</code> → <code class="language-plaintext highlighter-rouge">githubToken</code> 変数にトークンを入力してください。</p>

<p><strong>GithubStub を GitHub に置き換える:</strong></p>

<p>GAS プロジェクト → <code class="language-plaintext highlighter-rouge">Settings.gs</code> → 次のように変更してください：</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">iOSGitHub</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">GitHubStub</span><span class="p">(</span><span class="nx">githubToken</span><span class="p">,</span> <span class="nx">iOSRepoPath</span><span class="p">);</span>
</code></pre></div></div>

<p><strong>変更後</strong></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">iOSGitHub</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">GitHub</span><span class="p">(</span><span class="nx">githubToken</span><span class="p">,</span> <span class="nx">iOSRepoPath</span><span class="p">);</span>
</code></pre></div></div>

<p>ファイルを保存する。</p>

<p><strong>テスト用「ウェブアプリ」URLをリロードして変更が正しいか確認してください:</strong></p>

<p><img src="/assets/4273e57e7148/1*30k1iDALT9WdupmuBiG2uQ.webp" alt="" loading="lazy" decoding="async" width="958" height="859" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTgiIGhlaWdodD0iODU5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*30k1iDALT9WdupmuBiG2uQ.png" /></p>

<blockquote>
  <p><em>データが正しく表示されている場合：<strong>GitHubが実際のデータへの接続に成功しました</strong> 🎉🎉🎉</em></p>
</blockquote>

<p>「Runner 状態」に切り替えて、Self-hosted Runner の状態が正常に取得できているか確認できます：</p>

<p><img src="/assets/4273e57e7148/1*K3yzISn5J7o1e1F5zhIQpg.webp" alt="" loading="lazy" decoding="async" width="972" height="394" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NzIiIGhlaWdodD0iMzk0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*K3yzISn5J7o1e1F5zhIQpg.png" /></p>

<p>注：私の Runner は起動していないため、オフラインです。</p>

<h4 id="slack-連携">Slack 連携</h4>

<p>Slack 通知を連携するために、まずはリポジトリの GitHub Actions に戻り、パッケージビルド Action を包む通知コンテナ Action を新規作成します。</p>

<p><strong>CD-Deploy-Form.yml:</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ワークフロー(Action) 名称</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">CD-Deploy-Form</span>

<span class="c1"># Actions ログのタイトル名</span>
<span class="na">run-name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">[CD-Deploy-Form]</span><span class="nv"> </span><span class="s">${{</span><span class="nv"> </span><span class="s">github.ref</span><span class="nv"> </span><span class="s">}}"</span>

<span class="c1"># 同じ Concurrency Group 内で新しいジョブがある場合、実行中のものをキャンセル</span>
<span class="c1"># 例：同じブランチのパッケージングタスクを繰り返しトリガーした場合、前のタスクをキャンセル</span>
<span class="na">concurrency</span><span class="pi">:</span>
  <span class="na">group</span><span class="pi">:</span> <span class="s">${{ github.workflow }}-${{ github.ref }}</span>
  <span class="na">cancel-in-progress</span><span class="pi">:</span> <span class="kc">true</span>

<span class="c1"># トリガーイベント</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># 手動フォームトリガー</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>
    <span class="c1"># フォームの入力欄</span>
    <span class="na">inputs</span><span class="pi">:</span>
      <span class="c1"># アプリのバージョン番号</span>
      <span class="na">VERSION_NUMBER</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">アプリのバージョン番号（例：1.0.0）。空欄の場合はXcodeプロジェクトから自動検出。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="c1"># アプリのビルド番号</span>
      <span class="na">BUILD_NUMBER</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">アプリのビルド番号（例：1）。空欄の場合はタイムスタンプを使用。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="c1"># アプリのリリースノート</span>
      <span class="na">RELEASE_NOTE</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">デプロイのリリースノート。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="c1"># トリガーしたユーザーのSlackユーザーID</span>
      <span class="na">SLACK_USER_ID</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">SlackユーザーID。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">true</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="c1"># トリガーしたユーザーのメールアドレス</span>
      <span class="na">AUTHOR</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">トリガーしたユーザーのメールアドレス。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">true</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
        
<span class="c1"># ジョブ</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="c1"># パッケージング開始時にSlackメッセージを送信</span>
  <span class="c1"># ジョブID</span>
  <span class="na">start-message</span><span class="pi">:</span>
    <span class="c1"># 小規模ジョブはGitHubホストランナーで実行、使用量は少ない</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    
    <span class="c1"># 最大タイムアウト時間を設定、異常時の無限待機を防止</span>
    <span class="c1"># 通常は5分以上かからない</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">5</span>

    <span class="c1"># ジョブのステップ</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Post a Start Slack Message</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">slack</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">slackapi/slack-github-action@v2.0.0</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">method</span><span class="pi">:</span> <span class="s">chat.postMessage</span>
          <span class="na">token</span><span class="pi">:</span> <span class="s">${{ secrets.SLACK_BOT_TOKEN }}</span>
          <span class="na">payload</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">channel</span><span class="err">:</span> <span class="s">${{ inputs.SLACK_USER_ID }}</span>
            <span class="s">text</span><span class="err">:</span> <span class="s2">"</span><span class="s">パッケージングリクエストを受け取りました。</span><span class="se">\n</span><span class="s">ID:</span><span class="nv"> </span><span class="s">&lt;${{</span><span class="nv"> </span><span class="s">github.server_url</span><span class="nv"> </span><span class="s">}}/${{</span><span class="nv"> </span><span class="s">github.repository</span><span class="nv"> </span><span class="s">}}/actions/runs/${{</span><span class="nv"> </span><span class="s">github.run_id</span><span class="nv"> </span><span class="s">}}</span><span class="se">\\</span><span class="s">|${{</span><span class="nv"> </span><span class="s">github.run_id</span><span class="nv"> </span><span class="s">}}&gt;</span><span class="se">\n</span><span class="s">Branch:</span><span class="nv"> </span><span class="s">${{</span><span class="nv"> </span><span class="s">github.ref_name</span><span class="nv"> </span><span class="s">}}</span><span class="se">\n</span><span class="s">cc'ed</span><span class="nv"> </span><span class="s">&lt;@${{</span><span class="nv"> </span><span class="s">inputs.SLACK_USER_ID</span><span class="nv"> </span><span class="s">}}&gt;"</span>
    <span class="c1"># ジョブの出力を後続ジョブで使用</span>
    <span class="c1"># ts = SlackメッセージID、後続通知で同スレッドに返信可能</span>
    <span class="na">outputs</span><span class="pi">:</span>
      <span class="na">ts</span><span class="pi">:</span> <span class="s">${{ steps.slack.outputs.ts }}</span>

  <span class="na">deploy</span><span class="pi">:</span>
    <span class="c1"># ジョブはデフォルトで並行実行、needsでstart-message完了待ちに制限</span>
    <span class="c1"># パッケージングデプロイタスクを実行</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="s">start-message</span>
    <span class="na">uses</span><span class="pi">:</span> <span class="s">./.github/workflows/CD-Deploy.yml</span>
    <span class="na">secrets</span><span class="pi">:</span> <span class="s">inherit</span>
    <span class="na">with</span><span class="pi">:</span>
      <span class="na">VERSION_NUMBER</span><span class="pi">:</span> <span class="s">${{ inputs.VERSION_NUMBER }}</span>
      <span class="na">BUILD_NUMBER</span><span class="pi">:</span> <span class="s">${{ inputs.BUILD_NUMBER }}</span>
      <span class="na">RELEASE_NOTE</span><span class="pi">:</span> <span class="s">${{ inputs.RELEASE_NOTE }}</span>
      <span class="na">AUTHOR</span><span class="pi">:</span> <span class="s">${{ inputs.AUTHOR }}</span>

  <span class="c1"># パッケージングデプロイ成功メッセージ</span>
  <span class="na">end-message-success</span><span class="pi">:</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">start-message</span><span class="pi">,</span> <span class="nv">deploy</span><span class="pi">]</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">${{ needs.deploy.result == 'success' }}</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">5</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Post a Success Slack Message</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">slackapi/slack-github-action@v2.0.0</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">method</span><span class="pi">:</span> <span class="s">chat.postMessage</span>
          <span class="na">token</span><span class="pi">:</span> <span class="s">${{ secrets.SLACK_BOT_TOKEN }}</span>
          <span class="na">payload</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">channel</span><span class="err">:</span> <span class="s">${{ inputs.SLACK_USER_ID }}</span>
            <span class="s">thread_ts</span><span class="err">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">needs.start-message.outputs.ts</span><span class="nv"> </span><span class="s">}}"</span>
            <span class="na">text</span><span class="pi">:</span> <span class="s2">"</span><span class="s">✅</span><span class="nv"> </span><span class="s">パッケージングとデプロイに成功しました。</span><span class="se">\n\n</span><span class="s">cc'ed</span><span class="nv"> </span><span class="s">&lt;@${{</span><span class="nv"> </span><span class="s">inputs.SLACK_USER_ID</span><span class="nv"> </span><span class="s">}}&gt;"</span>
  
  <span class="c1"># パッケージングデプロイ失敗メッセージ</span>
  <span class="na">end-message-failure</span><span class="pi">:</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">deploy</span><span class="pi">,</span> <span class="nv">start-message</span><span class="pi">]</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">${{ needs.deploy.result == 'failure' }}</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">5</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Post a Failure Slack Message</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">slackapi/slack-github-action@v2.0.0</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">method</span><span class="pi">:</span> <span class="s">chat.postMessage</span>
          <span class="na">token</span><span class="pi">:</span> <span class="s">${{ secrets.SLACK_BOT_TOKEN }}</span>
          <span class="na">payload</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">channel</span><span class="err">:</span> <span class="s">${{ inputs.SLACK_USER_ID }}</span>
            <span class="s">thread_ts</span><span class="err">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">needs.start-message.outputs.ts</span><span class="nv"> </span><span class="s">}}"</span>
            <span class="na">text</span><span class="pi">:</span> <span class="s2">"</span><span class="s">❌</span><span class="nv"> </span><span class="s">パッケージングとデプロイに失敗しました。実行状況を確認するか、後ほど再試行してください。</span><span class="se">\n\n</span><span class="s">cc'ed</span><span class="nv"> </span><span class="s">&lt;@${{</span><span class="nv"> </span><span class="s">inputs.SLACK_USER_ID</span><span class="nv"> </span><span class="s">}}&gt;"</span>

  <span class="c1"># パッケージングデプロイキャンセルメッセージ</span>
  <span class="na">end-message-cancelled</span><span class="pi">:</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">deploy</span><span class="pi">,</span> <span class="nv">start-message</span><span class="pi">]</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">${{ needs.deploy.result == 'cancelled' }}</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">5</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Post a Cancelled Slack Message</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">slackapi/slack-github-action@v2.0.0</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">method</span><span class="pi">:</span> <span class="s">chat.postMessage</span>
          <span class="na">token</span><span class="pi">:</span> <span class="s">${{ secrets.SLACK_BOT_TOKEN }}</span>
          <span class="na">payload</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">channel</span><span class="err">:</span> <span class="s">${{ inputs.SLACK_USER_ID }}</span>
            <span class="s">thread_ts</span><span class="err">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">needs.start-message.outputs.ts</span><span class="nv"> </span><span class="s">}}"</span>
            <span class="na">text</span><span class="pi">:</span> <span class="s2">"</span><span class="s">:black_square_for_stop:</span><span class="nv"> </span><span class="s">パッケージングとデプロイがキャンセルされました。</span><span class="se">\n\n</span><span class="s">cc'ed</span><span class="nv"> </span><span class="s">&lt;@${{</span><span class="nv"> </span><span class="s">inputs.SLACK_USER_ID</span><span class="nv"> </span><span class="s">}}&gt;"</span>
</code></pre></div></div>

<p><strong>完全なコード：</strong> <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/CD-Deploy-Form.yml" target="_blank">CD-Deploy-Form.yml</a></p>

<p><img src="/assets/4273e57e7148/1*NatyC_Oid4BrKYk4nehuKA.webp" alt="" loading="lazy" decoding="async" width="952" height="287" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTIiIGhlaWdodD0iMjg3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*NatyC_Oid4BrKYk4nehuKA.png" /></p>

<p>この Action は単なるコンテナで、Slack 通知と連携しています。実際には、<a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/">前回の記事</a>で作成した <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/CD-Deploy.yml" target="_blank">CD-Deploy.yml</a> Action を再利用しています。</p>

<ul>
  <li>
    <p>Slack Bot App の作成とメッセージ送信権限の設定については、私の<a href="/posts/zrealm-ロボティックプロセスオートメーション/slackとchatgpt連携-openai-apiで自作slackアプリをpythonとgoogle-cloud-functionsで実装-bd94cc88f9c9/">以前の記事</a>を参照してください。</p>
  </li>
  <li>
    <p>Repo → Secrets に対応する <code class="language-plaintext highlighter-rouge">SLACK_BOT_TOKEN</code> を追加し、Slack Bot App のトークン値を設定することを忘れないでください。</p>
  </li>
</ul>

<p>GAS プロジェクトに戻り → <code class="language-plaintext highlighter-rouge">Credentials.gs</code> → <code class="language-plaintext highlighter-rouge">slackBotToken</code> 変数にトークンを入力してください。</p>

<p>再到 GAS プロジェクト → <code class="language-plaintext highlighter-rouge">Settings.gs</code> → 次のように変更してください：</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">slack</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SlackStub</span><span class="p">(</span><span class="nx">slackBotToken</span><span class="p">);</span>
</code></pre></div></div>

<p><strong>変更後</strong></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">slack</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Slack</span><span class="p">(</span><span class="nx">slackBotToken</span><span class="p">);</span>
</code></pre></div></div>

<p>ファイルを保存する。</p>

<blockquote>
  <p><em>もし既存の Slack Bot App がなく通知を送るのが面倒な場合は、ここでのすべての手順を無視して、GAS プロジェクト内の slack に関する使用部分を削除してください。</em></p>
</blockquote>

<h4 id="github-連携--パッケージフォーム">GitHub 連携 — パッケージフォーム</h4>

<p>GAS プロジェクト → <code class="language-plaintext highlighter-rouge">Controller_iOS.gs</code> → <code class="language-plaintext highlighter-rouge">View_iOS_Form.html</code> の内容を調整：<br />
ダミーの Asana タスク連携方法を削除：</p>

<pre><code class="language-php-template">      &lt;? tasks.forEach(function(task) { ?&gt;
      &lt;option value="&lt;?=task.githubBranch?&gt;"&gt;[&lt;?=task.id?&gt;] &lt;?=task.title?&gt;&lt;/option&gt;
      &lt;? }) ?&gt;
</code></pre>

<p>ここでデフォルトブランチ（ここでは <code class="language-plaintext highlighter-rouge">main</code> ）を自分で調整することもできます。</p>

<p>—</p>

<p>GAS プロジェクト → <code class="language-plaintext highlighter-rouge">Controller_iOS.gs</code> → <code class="language-plaintext highlighter-rouge">iOSLoadForm()</code> の内容を調整:</p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">template.tasks = Stubable.fetchStubAsanaTasks();</code> の Asana のスタブ接続メソッドを削除してください。<br />
Asana や Jira と連携したい場合は、直接 ChatGPT に連携方法を尋ねてください。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">template.prs = iOSGitHub.fetchOpenPRs();</code> は実際に GitHub API を呼び出してオープン中の PR リストを取得します。必要に応じて残してください。</p>
  </li>
</ul>

<p><strong>送信後の処理</strong> <code class="language-plaintext highlighter-rouge">iOSSubmitForm()</code> の内容:</p>

<p>実際の GitHub Actions ワークフローファイル名や <code class="language-plaintext highlighter-rouge">workflow_dispatch</code> の inputs パラメータに応じて調整してください：</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="nx">iOSGitHub</span><span class="p">.</span><span class="nf">dispatchWorkflow</span><span class="p">(</span><span class="dl">"</span><span class="s2">CD-Deploy-Form.yml</span><span class="dl">"</span><span class="p">,</span> <span class="nx">branch</span><span class="p">,</span> <span class="p">{</span>
    <span class="dl">"</span><span class="s2">BUILD_NUMBER</span><span class="dl">"</span><span class="p">:</span> <span class="nx">buildNumber</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">VERSION_NUMBER</span><span class="dl">"</span><span class="p">:</span> <span class="nx">versionNumber</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">VERSION_NUMBER</span><span class="dl">"</span><span class="p">:</span> <span class="nx">versionNumber</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">RELEASE_NOTE</span><span class="dl">"</span><span class="p">:</span> <span class="nx">releaseNote</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">AUTHOR</span><span class="dl">"</span><span class="p">:</span> <span class="nx">email</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">SLACK_USER_ID</span><span class="dl">"</span><span class="p">:</span> <span class="nx">slack</span><span class="p">.</span><span class="nf">fetchUserID</span><span class="p">(</span><span class="nx">email</span><span class="p">)</span>
  <span class="p">});</span>
</code></pre></div></div>

<p>必須入力条件の検証も追加可能で、ここではブランチの入力が必須であることだけを検証し、入力がない場合はエラーメッセージが表示されます。</p>

<p>もしこれだけでは安全性が不十分だと感じる場合は、自分でパスワード認証を追加したり、特定のアカウントのみが使用できるように設定してください。</p>

<blockquote>
  <p><em>最後の一行 <strong>Slack通知機能はSlackの設定が必要です</strong>。Slack Bot Appがない場合やSlack連携をしたくない場合は、<a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/actions" target="_blank">Demo Actions Repo</a> で直接 <code class="language-plaintext highlighter-rouge">iOSGitHub.dispatchWorkflow("CD-Deploy.yml")</code> に変更し、<code class="language-plaintext highlighter-rouge">SLACK_USER_ID</code> パラメータを削除してください。</em></p>
</blockquote>

<p><strong>テスト用「ウェブアプリケーション」URLをリロードして変更が正しいか確認する：</strong></p>

<p><img src="/assets/4273e57e7148/1*OkJJrssZBcJPss_cMW-Qew.webp" alt="" loading="lazy" decoding="async" width="754" height="711" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NTQiIGhlaWdodD0iNzExIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*OkJJrssZBcJPss_cMW-Qew.png" /></p>

<p>パッケージングフォームには「Opened PR List」だけが残っています。</p>

<p><strong>必要な情報を入力して「送信リクエスト」を押し、ビルドフォームをテストしてください：</strong></p>

<p><img src="/assets/4273e57e7148/1*dl-g3j6GH0AnYL8dqvSyYA.webp" alt="" loading="lazy" decoding="async" width="523" height="252" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MjMiIGhlaWdodD0iMjUyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*dl-g3j6GH0AnYL8dqvSyYA.png" /></p>

<p><strong>送信が成功したことは問題ないことを意味し、パッケージング履歴に戻るとタスクが開始されているのも確認できます <em>🎉</em></strong> ：</p>

<p><img src="/assets/4273e57e7148/1*cByPF6T8WdXKionifRj1Ew.webp" alt="" loading="lazy" decoding="async" width="959" height="383" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTkiIGhlaWdodD0iMzgzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*cByPF6T8WdXKionifRj1Ew.png" /></p>

<blockquote>
  <p><em>重複したビルド記録は進行状況を更新できます。</em></p>
</blockquote>

<p><strong>よくある送信エラー：</strong></p>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">Required input ‘SLACK_USER_ID’ not provided</code> <em>: GitHub Actions のこの SLACK_USER_ID フィールドは必須ですが、渡されていません。Slack の設定が正しくないか、現在のユーザーのメールアドレスに対応する Slack のユーザーIDが見つからない可能性があります。</em></p>
</blockquote>

<blockquote>
  <p><em><code class="language-plaintext highlighter-rouge">Workflow does not have ‘workflow_dispatch’ trigger</code> 、 <code class="language-plaintext highlighter-rouge">分支過舊，請更新 xxx 分支</code> ：選択したブランチに対応する Action Workflow ファイル（iOSGitHub.dispatchWorkflow で指定されたファイル）が見つかりません。</em></p>
</blockquote>

<blockquote>
  <p><em><code class="language-plaintext highlighter-rouge">No ref found for</code> 、 <code class="language-plaintext highlighter-rouge">找不到分支</code> : このブランチが見つかりません。</em></p>
</blockquote>

<h3 id="firebase-app-distribution--ダウンロードリンク取得連携">Firebase App Distribution — ダウンロードリンク取得連携</h3>

<p>最後の小さな機能は Firebase App Distribution と連携し、ダウンロード情報とリンクを直接取得できるようにして、スマホでパッケージングプラットフォームツールを開いてすぐにダウンロード・インストールできるようにしました。</p>

<blockquote>
  <p><em>以前に「 <a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-script-firebase-app-distribution-apiとの高速連携方法-効率的なgoogle-apis統合-71400d408dc8/">Google Apps Script x Google APIs 迅速連携統合方法</a> 」を紹介しましたが、GAS は Firebase と簡単に連携できます。</em></p>
</blockquote>

<h4 id="接続の原理"><strong>接続の原理</strong></h4>

<blockquote>
  <p><strong><em>接続する前に、この「Tricky」の接続原理について説明します。</em></strong></p>
</blockquote>

<p>私たちのパッケージングプラットフォームにはデータベースがなく、純粋にAPIの中継ステーションとして機能しています。そのため、実際には<a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/actions/workflows/CD-Deploy.yml" target="_blank"><strong>GitHub Actions CD-Deploy.yml</strong></a> のパッケージング作業時に、Job Run IDをリリースノートに渡しています（もちろんビルド番号に渡すことも可能です）：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">ID</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="p">{ github.run_id </span><span class="k">}</span><span class="s2">}"</span> // ジョブ実行ID
<span class="nv">COMMIT_SHA</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="p">{ github.sha </span><span class="k">}</span><span class="s2">}"</span>
<span class="nv">BRANCH_NAME</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="p">{ github.ref_name </span><span class="k">}</span><span class="s2">}"</span>
<span class="nv">AUTHOR</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="p">{ env.AUTHOR </span><span class="k">}</span><span class="s2">}"</span>

<span class="c"># リリースノートの作成</span>
<span class="nv">RELEASE_NOTE</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="p">{ env.RELEASE_NOTE </span><span class="k">}</span><span class="s2">}
ID: </span><span class="k">${</span><span class="nv">ID</span><span class="k">}</span><span class="s2">
Commit SHA: </span><span class="k">${</span><span class="nv">COMMIT_SHA</span><span class="k">}</span><span class="s2">
Branch: </span><span class="k">${</span><span class="nv">BRANCH_NAME</span><span class="k">}</span><span class="s2">
Author: </span><span class="k">${</span><span class="nv">AUTHOR</span><span class="k">}</span><span class="s2">
"</span>

<span class="c"># Fastlaneでのビルド＆デプロイLaneの実行</span>
bundle <span class="nb">exec </span>fastlane beta release_notes:<span class="s2">"</span><span class="k">${</span><span class="nv">RELEASE_NOTE</span><span class="k">}</span><span class="s2">"</span> version_number:<span class="s2">"</span><span class="k">${</span><span class="nv">VERSION_NUMBER</span><span class="k">}</span><span class="s2">"</span> build_number:<span class="s2">"</span><span class="k">${</span><span class="nv">BUILD_NUMBER</span><span class="k">}</span><span class="s2">"</span>
</code></pre></div></div>

<p>こうすることで、Firebase App Distribution のリリースノートに Job Run ID が表示されます。</p>

<p>GAS Web App パッケージツールプラットフォームは GitHub API と連携して GitHub Actions の実行履歴を取得します。API から取得した Job Run ID を使って Firebase App Distribution API でリリースノートに <code class="language-plaintext highlighter-rouge">*ID: XXX*</code> を含むバージョンを検索すれば、対応するパッケージ履歴を見つけることができます。</p>

<p><strong>データベースを使わずに、2つのツールプラットフォームの連携が可能。</strong></p>

<p><img src="/assets/4273e57e7148/1*AJRMWv_rqu64H0ZrY4q6QA.webp" alt="" loading="lazy" decoding="async" width="559" height="347" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTkiIGhlaWdodD0iMzQ3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*AJRMWv_rqu64H0ZrY4q6QA.png" /></p>

<p><img src="/assets/4273e57e7148/1*Sdzt1MDXh7TNnMDkpc5uJg.webp" alt="" loading="lazy" decoding="async" width="1055" height="702" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDU1IiBoZWlnaHQ9IjcwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4273e57e7148/1*Sdzt1MDXh7TNnMDkpc5uJg.png" /></p>

<h4 id="プロジェクト連携設定">プロジェクト連携設定</h4>

<p>GAS → プロジェクト設定 → Google Cloud Platform (GCP) プロジェクト → プロジェクトを変更：</p>

<p><img src="/assets/4273e57e7148/1*klclBbiBQXNBzbzzj1jH0Q.webp" alt="" loading="lazy" decoding="async" width="1140" height="1115" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQwIiBoZWlnaHQ9IjExMTUiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/4273e57e7148/1*klclBbiBQXNBzbzzj1jH0Q.png" /></p>

<p><img src="/assets/4273e57e7148/1*gv8m_v5O_yyUrq8uQoverQ.webp" alt="" loading="lazy" decoding="async" width="1086" height="632" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDg2IiBoZWlnaHQ9IjYzMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4273e57e7148/1*gv8m_v5O_yyUrq8uQoverQ.png" /></p>

<p>接続したい Firebase プロジェクトの番号を入力してください。</p>

<p><img src="/assets/4273e57e7148/1*OEaxA6SZWYbiVstOK60hQg.webp" alt="" loading="lazy" decoding="async" width="760" height="444" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjAiIGhlaWdodD0iNDQ0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*OEaxA6SZWYbiVstOK60hQg.png" /></p>

<blockquote>
  <p><strong><em>初回設定でエラーが発生することがあります</em></strong><br />
<em>「プロジェクトを変更するには、OAuth 同意画面を設定してください。OAuth 同意画面の詳細設定。」と表示された場合は設定してください。表示されない場合は以下の手順をスキップして問題ありません。</em></p>
</blockquote>

<p><strong>「OAuth 同意画面の詳細情報」リンクをクリック → 「同意画面の設定」をクリック：</strong></p>

<p><img src="/assets/4273e57e7148/1*oiZeO5mEqH-D3tHrJsnE1A.webp" alt="" loading="lazy" decoding="async" width="1149" height="676" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQ5IiBoZWlnaHQ9IjY3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4273e57e7148/1*oiZeO5mEqH-D3tHrJsnE1A.png" /></p>

<p><strong>「開始」をクリック:</strong></p>

<p><img src="/assets/4273e57e7148/1*NK9RG0kaXoxJB5X-B8vhww.webp" alt="" loading="lazy" decoding="async" width="762" height="550" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjIiIGhlaWdodD0iNTUwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*NK9RG0kaXoxJB5X-B8vhww.png" /></p>

<p><strong>アプリケーション情報:</strong></p>

<ul>
  <li>
    <p>アプリケーション名: <code class="language-plaintext highlighter-rouge">あなたのツール名を入力してください</code></p>
  </li>
  <li>
    <p>ユーザーサポートメール: <code class="language-plaintext highlighter-rouge">選択したメール</code></p>
  </li>
</ul>

<p><strong>対象者:</strong></p>

<ul>
  <li>
    <p>内部：組織内のメンバーのみ利用可能</p>
  </li>
  <li>
    <p>外部：すべての Google アカウントユーザーが同意と認証後に利用可能</p>
  </li>
</ul>

<p><strong>連絡先情報:</strong></p>

<ul>
  <li>通知を受け取るメールアドレスを入力してください</li>
</ul>

<p><strong>《<a href="https://developers.google.com/terms/api-services-user-data-policy?hl=zh_TW" target="_blank">Google API サービス：ユーザーデータポリシー</a>》に同意するにチェックしてください。</strong></p>

<p>最後に「<strong>作成</strong>」をクリックします。</p>

<p>—</p>

<p>GAS に戻り → プロジェクト設定 → Google Cloud Platform (GCP) プロジェクト → プロジェクトを変更：</p>

<p>Firebase プロジェクト番号を再度入力し、「プロジェクトを変更」をクリックしてください。</p>

<p><img src="/assets/4273e57e7148/1*g-Lo04WjhaDjtXeXthNtDg.webp" alt="" loading="lazy" decoding="async" width="779" height="272" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzkiIGhlaWdodD0iMjcyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*g-Lo04WjhaDjtXeXthNtDg.png" /></p>

<p><strong>エラーが表示されなければ、バインディングは完了です。</strong></p>

<p>—</p>

<p><strong>「外部」を選択した場合、以下の設定も必要になることがあります：</strong></p>

<p>「プロジェクト番号」をクリック → 左側メニューを展開 → 「API とサービス」→ 「OAuth 同意画面」</p>

<p><img src="/assets/4273e57e7148/1*RJNQv8v3KZoTcVwUbsXSHQ.webp" alt="" loading="lazy" decoding="async" width="808" height="719" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MDgiIGhlaWdodD0iNzE5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*RJNQv8v3KZoTcVwUbsXSHQ.png" /></p>

<p>「対象ユーザー」を選択 → テスト → 「アプリケーションをデプロイ」をクリック → 完了。</p>

<p><img src="/assets/4273e57e7148/1*8vqrxhchsILPy4eSdvXfNg.webp" alt="" loading="lazy" decoding="async" width="626" height="445" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MjYiIGhlaWdodD0iNDQ1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*8vqrxhchsILPy4eSdvXfNg.png" /></p>

<blockquote>
  <p><em>ユーザーは前述の「 <strong>ユーザー初回利用時に同意が必要</strong> 」の手順に従って認証を完了すれば、すぐに利用可能です！</em></p>
</blockquote>

<p><strong>もし上記の手順を設定していない場合、ユーザーは以下のエラーに遭遇します：</strong></p>

<p><img src="/assets/4273e57e7148/1*2omUPFoubsrXVLHBPFkPbg.webp" alt="アクセスがブロックされました「XXX」はGoogle認証手続きが完了していません" loading="lazy" decoding="async" width="766" height="673" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjYiIGhlaWdodD0iNjczIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*2omUPFoubsrXVLHBPFkPbg.png" /></p>

<p>アクセス権「XXX」はGoogle認証プロセスが未完了のためブロックされました</p>

<p>— — —</p>

<h4 id="プロジェクトの連携">プロジェクトの連携</h4>

<p>連携に戻ると、Firebase は <code class="language-plaintext highlighter-rouge">ScriptApp.getOAuthToken()</code> を使って実行ユーザーの権限に応じたトークンを動的に取得するため、トークンの設定は不要です。</p>

<p>只需要 GAS プロジェクト → <code class="language-plaintext highlighter-rouge">Settings.gs</code> → に移動して、以下を設定してください：</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">iOSFirebase</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FirebaseStub</span><span class="p">(</span><span class="nx">iOSFirebaseProject</span><span class="p">);</span>
</code></pre></div></div>

<p><strong>変更後</strong></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">iOSFirebase</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Firebase</span><span class="p">(</span><span class="nx">iOSFirebaseProject</span><span class="p">);</span>
</code></pre></div></div>

<p>了解しました。</p>

<p><strong>テスト用「ウェブアプリ」URLをリロードしてパッケージ履歴へ → 任意の履歴を選んで「ダウンロードリンクを取得」をクリック：</strong></p>

<p><img src="/assets/4273e57e7148/1*9z-KsIAL5jyEzQvJv3YLgg.webp" alt="" loading="lazy" decoding="async" width="913" height="452" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTMiIGhlaWdodD0iNDUyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*9z-KsIAL5jyEzQvJv3YLgg.png" /></p>

<p><img src="/assets/4273e57e7148/1*q0HUYN2W3UonQLzwxZKXdQ.webp" alt="" loading="lazy" decoding="async" width="1179" height="2556" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTc5IiBoZWlnaHQ9IjI1NTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/4273e57e7148/1*q0HUYN2W3UonQLzwxZKXdQ.png" /></p>

<p>Firebase App Distribution のリリースノートで対応する Job Run Id のビルドが見つかった場合、ダウンロード情報が直接表示され、ダウンロードボタンをクリックすると直接ダウンロードページに移動します。</p>

<blockquote>
  <p>完了！🎉🎉🎉</p>
</blockquote>

<h3 id="成果">成果</h3>

<p><img src="/assets/4273e57e7148/1*znvPmqsaivk3KhsE26sFwA.webp" alt="Demo Web App" loading="lazy" decoding="async" width="1010" height="766" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDEwIiBoZWlnaHQ9Ijc2NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4273e57e7148/1*znvPmqsaivk3KhsE26sFwA.png" /></p>

<p><a href="https://script.google.com/macros/s/AKfycbwNW6N5ozKbIz_E1HK6yFEUtA8KQrUciS-jcPsQptvIKlARmKgLxbQzNu8ksVeg-BmEfg/exec" target="_blank">Demo Web App</a></p>

<p>ここまでで、サンプルはすべて実際に使えるビルドツールに変更済みです。あとはカスタマイズ機能や、より多くのサードパーティAPI連携、追加のフォームなどを自由に拡張できます（ChatGPTと相談しながら）。</p>

<blockquote>
  <p><em>最後に、開発とテストが完了したら、必ず前述の手順に従って — <strong>デプロイの更新を行わないと反映されません！</strong></em></p>
</blockquote>

<h3 id="連携の拡張">連携の拡張</h3>

<p>中継サーバーの役割を引き続き踏まえ、ここにいくつかの素早く連携するためのチートシートを提供します：</p>

<p><a href="https://developers.asana.com/reference/gettasksforproject" target="_blank"><strong>Asana API — タスクの取得:</strong></a></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="kd">function</span> <span class="nf">asanaAPI</span><span class="p">(</span><span class="nx">endPoint</span><span class="p">,</span> <span class="nx">method</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">GET</span><span class="dl">"</span><span class="p">,</span> <span class="nx">data</span> <span class="o">=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
      <span class="dl">"</span><span class="s2">method</span><span class="dl">"</span> <span class="p">:</span> <span class="nx">method</span><span class="p">,</span>
      <span class="dl">"</span><span class="s2">headers</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
          <span class="dl">"</span><span class="s2">Authorization</span><span class="dl">"</span><span class="p">:</span>  <span class="dl">"</span><span class="s2">Bearer </span><span class="dl">"</span><span class="o">+</span><span class="nx">asanaToken</span>
      <span class="p">},</span>
      <span class="dl">"</span><span class="s2">payload</span><span class="dl">"</span> <span class="p">:</span> <span class="nx">data</span>
    <span class="p">};</span>

    <span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://app.asana.com/api/1.0</span><span class="dl">"</span><span class="o">+</span><span class="nx">endPoint</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">res</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span>
    <span class="k">return</span> <span class="nx">data</span><span class="p">;</span>
<span class="p">}</span>

<span class="nf">asanaAPI</span><span class="p">(</span><span class="dl">"</span><span class="s2">/projects/{project_gid}/tasks</span><span class="dl">"</span><span class="p">)</span>
</code></pre></div></div>

<p><a href="https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#about" target="_blank"><strong>Jira API — チケット取得（JQL）:</strong></a></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// jql = フィルター条件</span>
<span class="kd">function</span> <span class="nf">jiraTickets</span><span class="p">(</span><span class="nx">jql</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="s2">`https://xxx.atlassian.net/rest/api/3/search`</span><span class="p">;</span>
  <span class="kd">const</span> <span class="nx">maxResults</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>

  <span class="kd">let</span> <span class="nx">allIssues</span> <span class="o">=</span> <span class="p">[];</span>
  <span class="kd">let</span> <span class="nx">startAt</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="kd">let</span> <span class="nx">total</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

  <span class="k">do</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">queryParams</span> <span class="o">=</span> <span class="p">{</span>
      <span class="na">jql</span><span class="p">:</span> <span class="nx">jql</span><span class="p">,</span>
      <span class="na">startAt</span><span class="p">:</span> <span class="nx">startAt</span><span class="p">,</span>
      <span class="na">maxResults</span><span class="p">:</span> <span class="nx">maxResults</span><span class="p">,</span>
      <span class="na">fields</span><span class="p">:</span> <span class="dl">"</span><span class="s2">assignee,summary,status</span><span class="dl">"</span>
    <span class="p">};</span>

    <span class="kd">const</span> <span class="nx">queryString</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nf">keys</span><span class="p">(</span><span class="nx">queryParams</span><span class="p">)</span>
      <span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="nx">key</span> <span class="o">=&gt;</span> <span class="s2">`</span><span class="p">${</span><span class="nf">encodeURIComponent</span><span class="p">(</span><span class="nx">key</span><span class="p">)}</span><span class="s2">=</span><span class="p">${</span><span class="nf">encodeURIComponent</span><span class="p">(</span><span class="nx">queryParams</span><span class="p">[</span><span class="nx">key</span><span class="p">])}</span><span class="s2">`</span><span class="p">)</span>
      <span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="dl">"</span><span class="s2">&amp;</span><span class="dl">"</span><span class="p">);</span>

    <span class="kd">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
      <span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">get</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">Authorization</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Basic </span><span class="dl">"</span> <span class="o">+</span> <span class="nx">jiraToken</span><span class="p">,</span>
        <span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span>
      <span class="p">},</span>
      <span class="na">muteHttpExceptions</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="p">};</span>

    <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">url</span><span class="p">}</span><span class="s2">?</span><span class="p">${</span><span class="nx">queryString</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
    <span class="kd">const</span> <span class="nx">json</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getResponseCode</span><span class="p">()</span> <span class="o">!=</span> <span class="mi">200</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Jiraの課題の取得に失敗しました。</span><span class="dl">"</span><span class="p">);</span> 
    <span class="p">}</span>

    <span class="k">if </span><span class="p">(</span><span class="nx">json</span><span class="p">.</span><span class="nx">issues</span> <span class="o">&amp;&amp;</span> <span class="nx">json</span><span class="p">.</span><span class="nx">issues</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">allIssues</span> <span class="o">=</span> <span class="nx">allIssues</span><span class="p">.</span><span class="nf">concat</span><span class="p">(</span><span class="nx">json</span><span class="p">.</span><span class="nx">issues</span><span class="p">);</span>
      <span class="nx">total</span> <span class="o">=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">total</span><span class="p">;</span>
      <span class="nx">startAt</span> <span class="o">+=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">issues</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="k">break</span><span class="p">;</span>
    <span class="p">}</span>
  <span class="p">}</span> <span class="k">while </span><span class="p">(</span><span class="nx">startAt</span> <span class="o">&lt;</span> <span class="nx">total</span><span class="p">);</span>

  <span class="kd">var</span> <span class="nx">groupIssues</span> <span class="o">=</span> <span class="p">{};</span>
  <span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">allIssues</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">issue</span> <span class="o">=</span> <span class="nx">allIssues</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">groupIssues</span><span class="p">[</span><span class="nx">issue</span><span class="p">.</span><span class="nx">fields</span><span class="p">.</span><span class="nx">status</span><span class="p">.</span><span class="nx">name</span><span class="p">]</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">groupIssues</span><span class="p">[</span><span class="nx">issue</span><span class="p">.</span><span class="nx">fields</span><span class="p">.</span><span class="nx">status</span><span class="p">.</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="p">}</span>
    <span class="nx">groupIssues</span><span class="p">[</span><span class="nx">issue</span><span class="p">.</span><span class="nx">fields</span><span class="p">.</span><span class="nx">status</span><span class="p">.</span><span class="nx">name</span><span class="p">].</span><span class="nf">push</span><span class="p">(</span><span class="nx">issue</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="nx">groupIssues</span><span class="p">;</span>
<span class="p">}</span>

<span class="nf">jiraTickets</span><span class="p">(</span><span class="s2">`project IN(App)`</span><span class="p">);</span>
</code></pre></div></div>

<p><strong>もし本当にデータベースが必要な場合は、Google Sheet を代わりに使用できます：</strong></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Saveable</span> <span class="p">{</span>
  <span class="nf">constructor</span><span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// https://docs.google.com/spreadsheets/d/Sheet-ID/edit</span>
    <span class="kd">const</span> <span class="nx">spreadsheet</span> <span class="o">=</span> <span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nf">openById</span><span class="p">(</span><span class="dl">"</span><span class="s2">Sheet-ID</span><span class="dl">"</span><span class="p">);</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">sheet</span> <span class="o">=</span> <span class="nx">spreadsheet</span><span class="p">.</span><span class="nf">getSheetByName</span><span class="p">(</span><span class="dl">"</span><span class="s2">Data</span><span class="dl">"</span><span class="p">);</span> <span class="c1">// シート名</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="nx">type</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="nf">write</span><span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">sheet</span><span class="p">.</span><span class="nf">appendRow</span><span class="p">([</span>
      <span class="k">this</span><span class="p">.</span><span class="nx">type</span><span class="p">,</span>
      <span class="nx">key</span><span class="p">,</span>
      <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span>
    <span class="p">]);</span>
  <span class="p">}</span>

  <span class="nf">read</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">sheet</span><span class="p">.</span><span class="nf">getDataRange</span><span class="p">().</span><span class="nf">getValues</span><span class="p">();</span>
    <span class="kd">const</span> <span class="nx">row</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="nx">r</span> <span class="o">=&gt;</span> <span class="nx">r</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">===</span> <span class="k">this</span><span class="p">.</span><span class="nx">type</span> <span class="o">&amp;&amp;</span> <span class="nx">r</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">===</span> <span class="nx">key</span><span class="p">);</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">row</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">let</span> <span class="nx">saveable</span> <span class="o">=</span> <span class="nc">Saveable</span><span class="p">(</span><span class="dl">"</span><span class="s2">user</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// 書き込み</span>
<span class="nx">saveable</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="dl">"</span><span class="s2">birthday_zhgchgli</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">0718</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// 読み込み</span>
<span class="nx">saveable</span><span class="p">.</span><span class="nf">read</span><span class="p">(</span><span class="dl">"</span><span class="s2">birthday_zhgchgli</span><span class="dl">"</span><span class="p">);</span> <span class="c1">// -&gt; 0718</span>
</code></pre></div></div>

<p><a href="https://api.slack.com/methods/chat.postMessage" target="_blank"><strong>Slack API とメッセージ送信方法：</strong></a></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">slackSendMessage</span><span class="p">(</span><span class="nx">channel</span><span class="p">,</span> <span class="nx">text</span> <span class="o">=</span> <span class="dl">""</span><span class="p">,</span> <span class="nx">blocks</span> <span class="o">=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">content</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">channel</span><span class="p">:</span> <span class="nx">channel</span><span class="p">,</span>
    <span class="na">unfurl_links</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
    <span class="na">unfurl_media</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
    <span class="na">text</span><span class="p">:</span> <span class="nx">text</span><span class="p">,</span>
    <span class="na">blocks</span><span class="p">:</span> <span class="nx">blocks</span>
  <span class="p">};</span>

  <span class="k">try</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nf">slackRequest</span><span class="p">(</span><span class="dl">"</span><span class="s2">chat.postMessage</span><span class="dl">"</span><span class="p">,</span> <span class="nx">content</span><span class="p">);</span>
    <span class="k">return</span> <span class="nx">response</span><span class="p">;</span>
  <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="s2">`Slackメッセージの送信に失敗しました: </span><span class="p">${</span><span class="nx">error</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">slackRequest</span><span class="p">(</span><span class="nx">path</span><span class="p">,</span> <span class="nx">content</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">post</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">contentType</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">Authorization</span><span class="p">:</span> <span class="s2">`Bearer </span><span class="p">${</span><span class="nx">slackBotToken</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span>
      <span class="dl">'</span><span class="s1">X-Slack-No-Retry</span><span class="dl">'</span><span class="p">:</span> <span class="mi">1</span>
    <span class="p">},</span>
    <span class="na">payload</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">content</span><span class="p">)</span>
  <span class="p">};</span>

  <span class="k">try</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="dl">"</span><span class="s2">https://slack.com/api/</span><span class="dl">"</span><span class="o">+</span><span class="nx">path</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
    <span class="kd">const</span> <span class="nx">responseData</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">responseData</span><span class="p">.</span><span class="nx">ok</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span> <span class="nx">responseData</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="s2">`Slack: </span><span class="p">${</span><span class="nx">responseData</span><span class="p">.</span><span class="nx">error</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="もっと多くの-google-apps-script-事例">もっと多くの Google Apps Script 事例：</h4>

<ul>
  <li>
    <p><a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-script-firebase-app-distribution-apiとの高速連携方法-効率的なgoogle-apis統合-71400d408dc8/">Google Apps Script x Google APIs の高速連携方法</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティック-プロセス-オートメーション/ga4自動数値通知ロボット-無料で作る3ステップ-google-apps-scriptとtelegram-bot連携-1e85b8df2348/">簡単3ステップ — 無料でGA4自動データ通知ロボットを作成</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティックプロセスオートメーション/google-apps-scriptで毎日データ報告をrpa自動化-効率化と正確性向上の秘訣-f6713ba3fee3/">Google Apps Script を使った毎日のデータレポート RPA 自動化</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティックプロセスオートメーション/slackとchatgpt連携-openai-apiで自作slackアプリをpythonとgoogle-cloud-functionsで実装-bd94cc88f9c9/">Slack &amp; ChatGPT Integration</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealmロボティックプロセスオートメーション/google-apps-script-3ステップで無料構築-github-repo-star通知をline連携で実現-382218e15697/">Google Apps Scriptを使って3ステップで無料でGithubリポジトリスター通知を作成する</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティック-プロセス-オートメーション/crashlyticsとgoogle-analytics連携-appのcrash-free-users率を自動取得する方法-793cb8f89b72/">Crashlytics + Google Analytics 自動でアプリのクラッシュフリーユーザー率を取得</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティック-プロセス-オートメーション/crashlyticsとbig-query連携-slackで即時にクラッシュ追跡を実現-e77b80cc6f89/">Crashlytics + Big Queryでよりリアルタイムで便利なクラッシュ追跡ツールを作る</a></p>
  </li>
</ul>

<h3 id="まとめ">まとめ</h3>

<p>ご覧いただき、またご参加いただきありがとうございます。CI/CD 0から1シリーズはここで一区切りとなります。皆様とチームのCI/CDワークフロー構築に実際に役立ち、効率と製品の安定性向上につながれば幸いです。実装に関するご質問があればぜひコメントでご相談ください。この4記事は約14日以上かけて執筆しました。<strong>もし気に入っていただけたら、ぜひ私のMediumをフォローし、友人や同僚にもシェアしてください。</strong></p>

<blockquote>
  <p>どういたしまして。</p>
</blockquote>

<h4 id="-buy-me-a-beer-on-paypal"><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank">🍺 Buy me a beer on PayPal</a></h4>

<blockquote>
  <p><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank"><strong><em>本シリーズの記事は多くの時間と労力をかけて執筆しました。内容があなたやチームの業務効率や製品品質向上に役立った場合は、ぜひコーヒーをご馳走してください。ご支援ありがとうございます！</em></strong></a></p>
</blockquote>

<p><img src="/assets/4273e57e7148/1*QJj54G9gOjtQS-rbHVT1SQ.webp" alt="Buy me a coffee" loading="lazy" decoding="async" width="700" height="700" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiIGhlaWdodD0iNzAwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4273e57e7148/1*QJj54G9gOjtQS-rbHVT1SQ.png" /></p>

<p><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank">🍺 Buy me a beer on PayPal</a></p>

<h4 id="シリーズ記事">シリーズ記事：</h4>

<ul>
  <li>
    <p><a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/"><strong>CI/CD 実践ガイド（1）：CI/CD とは？CI/CD を使って安定かつ効率的な開発チームを作るには？ツールの選び方は？</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/"><strong>CI/CD 実践ガイド（二）：GitHub Actions と self-hosted Runner の使い方と構築大全</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/"><strong>CI/CD 実践ガイド（三）：GitHub Actions を使ったアプリプロジェクトの CI と CD ワークフローの実装</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/"><strong>CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</strong></a></p>
  </li>
</ul>

<p><em><a href="https://medium.com/zrealm-ios-dev/ci-cd-%E5%AF%A6%E6%88%B0%E6%8C%87%E5%8D%97-%E5%9B%9B-%E4%BD%BF%E7%94%A8-google-apps-script-web-app-%E4%B8%B2%E6%8E%A5-github-actions-%E5%BB%BA%E7%BD%AE%E5%85%8D%E8%B2%BB%E6%98%93%E7%94%A8%E7%9A%84%E6%89%93%E5%8C%85%E5%B7%A5%E5%85%B7%E5%B9%B3%E5%8F%B0-4273e57e7148" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>により変換。</em></p>]]></content>
  </entry><entry>
    <title type="html">GitHub Actions｜iOS App CI/CD 自動化構築でビルドからデプロイまで最速実現</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/github-actions-ios-app-ci-cd-%E8%87%AA%E5%8B%95%E5%8C%96%E6%A7%8B%E7%AF%89%E3%81%A7%E3%83%93%E3%83%AB%E3%83%89%E3%81%8B%E3%82%89%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%BE%E3%81%A7%E6%9C%80%E9%80%9F%E5%AE%9F%E7%8F%BE-4b001d2e8440/" rel="alternate" type="text/html" title="GitHub Actions｜iOS App CI/CD 自動化構築でビルドからデプロイまで最速実現" />
    <published>2025-07-07T23:02:24+08:00</published>
    <updated>2026-01-04T11:38:01+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/4b001d2e8440</id><summary type="html">iOS開発者向けにGitHub Actionsでの自動ビルド、テスト、デプロイ手順を具体的に解説。手作業の負担を削減し、品質向上とリリース速度アップを実現します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="iosアプリ開発" /><category term="ci-cd" /><category term="github-actions" /><category term="firebase" /><category term="ci-cdパイプライン" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/4b001d2e8440/1*0LK6m6CTImL6rcsrliiOQA.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/github-actions-ios-app-ci-cd-%E8%87%AA%E5%8B%95%E5%8C%96%E6%A7%8B%E7%AF%89%E3%81%A7%E3%83%93%E3%83%AB%E3%83%89%E3%81%8B%E3%82%89%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%BE%E3%81%A7%E6%9C%80%E9%80%9F%E5%AE%9F%E7%8F%BE-4b001d2e8440/"><![CDATA[<h3 id="cicd-実践ガイド三github-actions-を使った-ios-アプリの-ci-と-cd-ワークフローの実装">CI/CD 実践ガイド（三）：GitHub Actions を使った iOS アプリの CI と CD ワークフローの実装</h3>

<p>iOSアプリの自動ビルド、テスト、デプロイを行うGitHub Actionsの実装手順完全ガイド</p>

<p><img src="/assets/4b001d2e8440/1*0LK6m6CTImL6rcsrliiOQA.webp" alt="Photo by Robs" loading="lazy" decoding="async" width="1200" height="801" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*0LK6m6CTImL6rcsrliiOQA.jpeg" /></p>

<p>Photo by <a href="https://unsplash.com/@robinne?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash" target="_blank">Robs</a></p>

<h4 id="はじめに">はじめに</h4>

<p>前回の「<a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/"><strong>CI/CD 実践ガイド（二）：GitHub Actions と Self-hosted Runner の使用と構築大全</strong></a>」では、GitHub Actions の基本知識と運用フロー、そして自分のマシンを Runner として使う方法について紹介し、3つの簡単な自動化 Actions を実装しました。<strong>本稿では、現実的に GitHub Actions を使って App（iOS）の CI/CD ワークフローを構築することに重点を置き</strong>、手取り足取りステップごとに進めながら GitHub Actions に関する知識も補足していきます。</p>

<h3 id="app-cicd-フロー関係図">App CI/CD フロー関係図</h3>

<p><img src="/assets/4b001d2e8440/1*VRygfRAkBRNEDAC4RyGzRA.webp" alt="" loading="lazy" decoding="async" width="1400" height="669" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjY2OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*VRygfRAkBRNEDAC4RyGzRA.png" /></p>

<p>本稿では GitHub Actions を使った CI/CD の構築部分に焦点を当てます。次回の記事「<a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/">CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</a>」で、右半分の Google Apps Script Web App を使ったチーム横断のパッケージングプラットフォーム構築について紹介します。</p>

<h4 id="運用フロー">運用フロー：</h4>

<ol>
  <li>
    <p>GitHub Actions で Pull Request トリガー、手動トリガー、またはスケジュールトリガー</p>
  </li>
  <li>
    <p>対応する Workflow のジョブ／ステップを実行する</p>
  </li>
  <li>
    <p>ステップに対応する Fastlane（iOS）または（Android Gradle）スクリプトを実行する</p>
  </li>
  <li>
    <p>Fastlane が実行する xcodebuild (iOS) コマンド</p>
  </li>
  <li>
    <p>実行結果を取得する</p>
  </li>
  <li>
    <p>後続の Workflow ジョブ／ステップの処理結果</p>
  </li>
  <li>
    <p>完了</p>
  </li>
</ol>

<h4 id="github-actions-成果図">GitHub Actions 成果図</h4>

<p>まず最終成果をお見せして、みなさんの実装意欲を高めましょう！</p>

<p><img src="/assets/4b001d2e8440/1*5gnQYdVAOtGR-bMK4ZrOhA.webp" alt="CI Testing" loading="lazy" decoding="async" width="911" height="566" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTEiIGhlaWdodD0iNTY2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*5gnQYdVAOtGR-bMK4ZrOhA.png" /></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/pull/11" target="_blank">CI Testing</a></p>

<p><img src="/assets/4b001d2e8440/1*u6A77KwkXS2SY5-DPPPR9A.webp" alt="" loading="lazy" decoding="async" width="1200" height="802" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*u6A77KwkXS2SY5-DPPPR9A.png" /></p>

<p><img src="/assets/4b001d2e8440/1*t9PrQfcTANyvG7gfXXC-bw.webp" alt="CI Nightly Build, CD Deploy" loading="lazy" decoding="async" width="554" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*t9PrQfcTANyvG7gfXXC-bw.jpeg" /></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/actions/runs/16119750747" target="_blank">CI Nightly Build, CD Deploy</a></p>

<h3 id="github-actions-x-self-hosted-runner-基礎知識">GitHub Actions x Self-hosted Runner 基礎知識</h3>

<p>もし GitHub Actions と Self-hosted Runner の構築にまだ慣れていない場合は、ぜひ前回の記事「<a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/"><strong>CI/CD 実践ガイド（二）：GitHub Actions と Self-hosted Runner の使い方と構築大全</strong></a>」を先にご覧いただくか、前回の知識と合わせて実践することを強くおすすめします。</p>

<blockquote>
  <p><strong><em>実装開始！</em></strong></p>
</blockquote>

<h3 id="ios-demo-プロジェクトのインフラ構成">iOS Demo プロジェクトのインフラ構成</h3>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo" target="_blank"><img src="https://opengraph.githubassets.com/eb233d74ad1bc6b0eceb9494487579557fb7f17066a3981d20b52fde2c00ef45/ZhgChgLi/github-actions-ci-cd-demo" alt="" /></a></p>

<p><strong>本文で使用する iOS プロジェクトの内容およびテスト項目はすべて AI によって生成されています</strong>。iOS のプログラムの詳細は気にせず、Infra と CI/CD の部分にのみ焦点を当てて議論します。</p>

<blockquote>
  <p><strong><em>以下のツールは過去の経験に基づいていますが、新しいプロジェクトでは最新の <a href="https://github.com/jdx/mise" target="_blank">mise</a> と <a href="https://github.com/tuist/tuist" target="_blank">tuist</a> の使用を検討してください。</em></strong></p>
</blockquote>

<h4 id="mint">Mint</h4>

<p><a href="https://github.com/yonaskolb/Mint" target="_blank"><img src="https://opengraph.githubassets.com/21a1c9531478638f34289d108bd478e5d7afec08dce1aa16123feb0e226a47a2/yonaskolb/Mint" alt="" /></a></p>

<p>Mint ツールは依存ツールのバージョンを統一管理できます（Gemfile は Ruby Gems のみ管理可能）。例えば、XCodeGen、SwiftFormat、SwiftLint、Periphery などです。</p>

<p>…など</p>

<p><strong>Mintfile:</strong></p>

<div class="language-graphql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">yonaskolb/Mint@0.17.5</span><span class="w">
</span><span class="err">yonaskolb/XcodeGen@2.35.0</span><span class="w">
</span><span class="err">nicklockwood/SwiftFormat@0.51.13</span><span class="w">
</span></code></pre></div></div>

<p>ここでは3つだけ使用します。</p>

<blockquote>
  <p><strong><em>複雑すぎると感じる場合は、使わなくても問題ありません。Action Workflow Step 内で直接 brew install を使って必要なツールをインストールしてください。</em></strong></p>
</blockquote>

<h4 id="bundle">Bundle</h4>

<p><strong>Gemfile:</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">source</span> <span class="s1">'https://rubygems.org'</span>
gem <span class="s1">'cocoapods'</span>, <span class="s1">'~&gt;1.16.0'</span>
gem <span class="s1">'fastlane'</span>, <span class="s1">'~&gt;2.228.0'</span>

plugins_path <span class="o">=</span> File.join<span class="o">(</span>File.dirname<span class="o">(</span>__FILE__<span class="o">)</span>, <span class="s1">'Product'</span>, <span class="s1">'fastlane'</span>, <span class="s1">'Pluginfile'</span><span class="o">)</span>
eval_gemfile<span class="o">(</span>plugins_path<span class="o">)</span> <span class="k">if </span>File.exist?<span class="o">(</span>plugins_path<span class="o">)</span>
</code></pre></div></div>

<p>Ruby（Gems）関連の依存関係を管理する場合、一般的なiOSプロジェクトでは主にこの2つ、<code class="language-plaintext highlighter-rouge">cocoapods</code> と <code class="language-plaintext highlighter-rouge">fastlane</code> がよく使われます。</p>

<h4 id="cocoapods">Cocoapods</h4>

<p><strong>Product/podfile:</strong></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">platform</span> <span class="ss">:ios</span><span class="p">,</span> <span class="s1">'13.0'</span>
<span class="n">use_frameworks!</span>

<span class="n">target</span> <span class="s1">'app-ci-cd-github-actions-demo'</span> <span class="k">do</span>
  <span class="n">pod</span> <span class="s1">'SnapKit'</span>
<span class="k">end</span> 
</code></pre></div></div>

<p><a href="https://blog.cocoapods.org/CocoaPods-Specs-Repo/" target="_blank">まもなくメンテナンス終了が宣言された</a> ものの、Cocoapods は古い iOS プロジェクトで依然としてよく使われています。ここでは簡単に Snapkit をデモとして追加します。</p>

<h4 id="xcodegen">XCodeGen</h4>

<p>多人開発での <code class="language-plaintext highlighter-rouge">.xcodeproj</code> / <code class="language-plaintext highlighter-rouge">.xcworkspace</code> の変更によるコンフリクトを避けるため、Project.yaml で XCode プロジェクトの内容を統一して定義し、ローカルで自分自身で Project ファイルを生成する（Git に上げない）。</p>

<p><strong>Product/project.yaml:</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">app-ci-cd-github-actions-demo</span>
<span class="na">options</span><span class="pi">:</span>
  <span class="na">bundleIdPrefix</span><span class="pi">:</span> <span class="s">com.example</span>
  <span class="na">deploymentTarget</span><span class="pi">:</span>
    <span class="na">iOS</span><span class="pi">:</span> <span class="s1">'</span><span class="s">13.0'</span>
  <span class="na">usesTabs</span><span class="pi">:</span> <span class="kc">false</span>
  <span class="na">indentWidth</span><span class="pi">:</span> <span class="m">2</span>
  <span class="na">tabWidth</span><span class="pi">:</span> <span class="m">2</span>

<span class="na">configs</span><span class="pi">:</span>
  <span class="na">Debug</span><span class="pi">:</span> <span class="s">debug</span>
  <span class="na">Release</span><span class="pi">:</span> <span class="s">release</span>

<span class="na">targets</span><span class="pi">:</span>
  <span class="na">app-ci-cd-github-actions-demo</span><span class="pi">:</span>
    <span class="na">type</span><span class="pi">:</span> <span class="s">application</span>
    <span class="na">platform</span><span class="pi">:</span> <span class="s">iOS</span>
    <span class="na">sources</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">app-ci-cd-github-actions-demo</span>
    <span class="na">resources</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">app-ci-cd-github-actions-demo/Assets.xcassets</span>
      <span class="pi">-</span> <span class="s">app-ci-cd-github-actions-demo/Base.lproj</span>
    <span class="na">info</span><span class="pi">:</span>
      <span class="na">path</span><span class="pi">:</span> <span class="s">app-ci-cd-github-actions-demo/Info.plist</span>
      <span class="na">properties</span><span class="pi">:</span>
        <span class="na">CFBundleIdentifier</span><span class="pi">:</span> <span class="s">$(PRODUCT_BUNDLE_IDENTIFIER)</span>
    <span class="na">settings</span><span class="pi">:</span>
      <span class="na">base</span><span class="pi">:</span>
        <span class="na">PRODUCT_BUNDLE_IDENTIFIER</span><span class="pi">:</span> <span class="s">com.test.appcicdgithubactionsdemo</span>
    <span class="na">cocoapods</span><span class="pi">:</span> <span class="kc">true</span>

  <span class="na">app-ci-cd-github-actions-demoTests</span><span class="pi">:</span>
    <span class="na">type</span><span class="pi">:</span> <span class="s">bundle.unit-test</span>
    <span class="na">platform</span><span class="pi">:</span> <span class="s">iOS</span>
    <span class="na">sources</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">app-ci-cd-github-actions-demoTests</span>
    <span class="na">dependencies</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">target</span><span class="pi">:</span> <span class="s">app-ci-cd-github-actions-demo</span>
    <span class="na">info</span><span class="pi">:</span>
      <span class="na">path</span><span class="pi">:</span> <span class="s">app-ci-cd-github-actions-demoTests/Info.plist</span>
    <span class="na">settings</span><span class="pi">:</span>
      <span class="na">base</span><span class="pi">:</span>
        <span class="na">PRODUCT_BUNDLE_IDENTIFIER</span><span class="pi">:</span> <span class="s">com.test.appcicdgithubactionsdemo.tests</span>

  <span class="na">app-ci-cd-github-actions-demoUITests</span><span class="pi">:</span>
    <span class="na">type</span><span class="pi">:</span> <span class="s">bundle.ui-testing</span>
    <span class="na">platform</span><span class="pi">:</span> <span class="s">iOS</span>
    <span class="na">sources</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">app-ci-cd-github-actions-demoUITests</span>
    <span class="na">dependencies</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">target</span><span class="pi">:</span> <span class="s">app-ci-cd-github-actions-demo</span>
    <span class="na">info</span><span class="pi">:</span>
      <span class="na">path</span><span class="pi">:</span> <span class="s">app-ci-cd-github-actions-demoUITests/Info.plist</span>
    <span class="na">settings</span><span class="pi">:</span>
      <span class="na">base</span><span class="pi">:</span>
        <span class="na">PRODUCT_BUNDLE_IDENTIFIER</span><span class="pi">:</span> <span class="s">com.test.appcicdgithubactionsdemo.uitests</span>

  <span class="na">app-ci-cd-github-actions-demoSnapshotTests</span><span class="pi">:</span>
    <span class="na">type</span><span class="pi">:</span> <span class="s">bundle.unit-test</span>
    <span class="na">platform</span><span class="pi">:</span> <span class="s">iOS</span>
    <span class="na">sources</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">path</span><span class="pi">:</span> <span class="s">app-ci-cd-github-actions-demoSnapshotTests</span>
        <span class="na">excludes</span><span class="pi">:</span>
          <span class="pi">-</span> <span class="s2">"</span><span class="s">**/__Snapshots__/**"</span>
    <span class="na">dependencies</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">target</span><span class="pi">:</span> <span class="s">app-ci-cd-github-actions-demo</span>
      <span class="pi">-</span> <span class="na">product</span><span class="pi">:</span> <span class="s">SnapshotTesting</span>
        <span class="na">package</span><span class="pi">:</span> <span class="s">SnapshotTesting</span>
    <span class="na">info</span><span class="pi">:</span>
      <span class="na">path</span><span class="pi">:</span> <span class="s">app-ci-cd-github-actions-demoSnapshotTests/Info.plist</span>
      <span class="na">settings</span><span class="pi">:</span>
        <span class="na">base</span><span class="pi">:</span>
          <span class="na">PRODUCT_BUNDLE_IDENTIFIER</span><span class="pi">:</span> <span class="s">com.test.appcicdgithubactionsdemo.snapshottests</span>

<span class="na">packages</span><span class="pi">:</span>
  <span class="na">SnapshotTesting</span><span class="pi">:</span>
    <span class="na">url</span><span class="pi">:</span> <span class="s">https://github.com/pointfreeco/swift-snapshot-testing</span>
    <span class="na">from</span><span class="pi">:</span> <span class="s">1.18.4</span>
</code></pre></div></div>

<p>SnapshotTesting: Swift Package Manager を使った管理。</p>

<h4 id="fastlane">Fastlane</h4>

<p>xcodebuildコマンドのラップ、App Store Connect APIやFirebase APIなどのサービス連携の複雑な手順のラップ。</p>

<p><strong>Product/fastlane/Fastfile:</strong></p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="nf">default_platform</span><span class="p">(</span><span class="o">:</span><span class="n">ios</span><span class="p">)</span>

<span class="n">platform</span> <span class="o">:</span><span class="n">ios</span> <span class="k">do</span>
  <span class="n">desc</span> <span class="s2">"すべてのテストを実行する（ユニットテスト＋UIテスト）"</span>
  <span class="n">lane</span> <span class="o">:</span><span class="n">run_all_tests</span> <span class="k">do</span> <span class="err">\\</span><span class="o">|</span><span class="n">options</span><span class="err">\\</span><span class="o">|</span>
    <span class="n">device</span> <span class="o">=</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">device</span><span class="p">]</span>
    <span class="nf">scan</span><span class="p">(</span>
      <span class="n">scheme</span><span class="o">:</span> <span class="s2">"app-ci-cd-github-actions-demo"</span><span class="p">,</span>
      <span class="n">device</span><span class="o">:</span> <span class="n">device</span><span class="p">,</span>
      <span class="n">clean</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
      <span class="n">output_directory</span><span class="o">:</span> <span class="s2">"fastlane/test_output"</span><span class="p">,</span>
      <span class="n">output_types</span><span class="o">:</span> <span class="s2">"junit"</span>
    <span class="p">)</span>
  <span class="n">end</span>

  <span class="n">desc</span> <span class="s2">"ユニットテストのみを実行する"</span>
  <span class="n">lane</span> <span class="o">:</span><span class="n">run_unit_tests</span> <span class="k">do</span> <span class="err">\\</span><span class="o">|</span><span class="n">options</span><span class="err">\\</span><span class="o">|</span>
    <span class="n">device</span> <span class="o">=</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">device</span><span class="p">]</span>
    <span class="nf">scan</span><span class="p">(</span>
      <span class="n">scheme</span><span class="o">:</span> <span class="s2">"app-ci-cd-github-actions-demo"</span><span class="p">,</span>
      <span class="n">device</span><span class="o">:</span> <span class="n">device</span><span class="p">,</span>
      <span class="n">clean</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
      <span class="n">only_testing</span><span class="o">:</span> <span class="p">[</span>
        <span class="s2">"app-ci-cd-github-actions-demoTests"</span>
      <span class="p">],</span>
      <span class="n">output_directory</span><span class="o">:</span> <span class="s2">"fastlane/test_output"</span><span class="p">,</span>
      <span class="n">output_types</span><span class="o">:</span> <span class="s2">"junit"</span>
    <span class="p">)</span>
  <span class="n">end</span>

  <span class="n">desc</span> <span class="s2">"ビルドしてFirebase App Distributionにアップロードする"</span>
  <span class="n">lane</span> <span class="o">:</span><span class="n">beta</span> <span class="k">do</span> <span class="err">\\</span><span class="o">|</span><span class="n">options</span><span class="err">\\</span><span class="o">|</span>
    
    <span class="k">if</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">version_number</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">version_number</span><span class="p">]</span><span class="mf">.</span><span class="n">to_s</span><span class="mf">.</span><span class="n">strip</span> <span class="o">!=</span> <span class="s2">""</span>
      <span class="nf">increment_version_number</span><span class="p">(</span><span class="n">version_number</span><span class="o">:</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">version_number</span><span class="p">])</span>
    <span class="n">end</span>

    <span class="k">if</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">build_number</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">build_number</span><span class="p">]</span><span class="mf">.</span><span class="n">to_s</span><span class="mf">.</span><span class="n">strip</span> <span class="o">!=</span> <span class="s2">""</span>
      <span class="nf">increment_build_number</span><span class="p">(</span><span class="n">build_number</span><span class="o">:</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">build_number</span><span class="p">])</span>
    <span class="n">end</span>

    <span class="nf">update_code_signing_settings</span><span class="p">(</span>
      <span class="n">use_automatic_signing</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
      <span class="n">path</span><span class="o">:</span> <span class="s2">"app-ci-cd-github-actions-demo.xcodeproj"</span><span class="p">,</span>
      <span class="n">team_id</span><span class="o">:</span> <span class="no">ENV</span><span class="p">[</span><span class="s1">'TEAM_ID'</span><span class="p">],</span>
      <span class="n">code_sign_identity</span><span class="o">:</span> <span class="s2">"iPhone Developer"</span><span class="p">,</span>
      <span class="n">sdk</span><span class="o">:</span> <span class="s2">"iphoneos*"</span><span class="p">,</span>
      <span class="n">profile_name</span><span class="o">:</span> <span class="s2">"cicd"</span>
    <span class="p">)</span>

    <span class="nf">gym</span><span class="p">(</span>
      <span class="n">scheme</span><span class="o">:</span> <span class="s2">"app-ci-cd-github-actions-demo"</span><span class="p">,</span>
      <span class="n">clean</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
      <span class="n">export_method</span><span class="o">:</span> <span class="s2">"development"</span><span class="p">,</span>
      <span class="n">output_directory</span><span class="o">:</span> <span class="s2">"fastlane/build"</span><span class="p">,</span>
      <span class="n">output_name</span><span class="o">:</span> <span class="s2">"app-ci-cd-github-actions-demo.ipa"</span><span class="p">,</span>
      <span class="n">export_options</span><span class="o">:</span> <span class="p">{</span>
          <span class="n">provisioningProfiles</span><span class="o">:</span> <span class="p">{</span>
            <span class="s2">"com.test.appcicdgithubactionsdemo"</span> <span class="o">=&gt;</span> <span class="s2">"cicd"</span><span class="p">,</span>
          <span class="p">},</span>
      <span class="p">}</span>
    <span class="p">)</span>

    <span class="nf">firebase_app_distribution</span><span class="p">(</span>
      <span class="n">app</span><span class="o">:</span> <span class="s2">"1:127683058219:ios:98896929fa131c7a80686e"</span><span class="p">,</span>
      <span class="n">firebase_cli_token</span><span class="o">:</span> <span class="no">ENV</span><span class="p">[</span><span class="s2">"FIREBASE_CLI_TOKEN"</span><span class="p">],</span>
      <span class="n">release_notes</span><span class="o">:</span> <span class="n">options</span><span class="p">[</span><span class="o">:</span><span class="n">release_notes</span><span class="p">]</span> <span class="err">\\</span><span class="o">|</span><span class="err">\\</span><span class="o">|</span> <span class="s2">"New beta build"</span>
    <span class="p">)</span>
  <span class="n">end</span>
<span class="n">end</span>
</code></pre></div></div>

<p>註：provisioningProfiles、profile_name は <a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">App Developer の Profiles 証明書名</a> に対応しています。（match を使用している場合は、これらの指定は不要です。）</p>

<p><img src="/assets/4b001d2e8440/1*WXqqnErto3nn8rnNg6TXgw.webp" alt="" loading="lazy" decoding="async" width="1117" height="616" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTE3IiBoZWlnaHQ9IjYxNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*WXqqnErto3nn8rnNg6TXgw.png" /></p>

<p><strong>Fastlane は iOS CI/CD において欠かせない存在</strong> であり、用意されたメソッドを使うだけで CI/CD の実際の実行ステップを素早く開発できます。私たちは全体のスクリプト設計に集中でき、複雑な API 連携やコマンド作成に悩む必要がありません。</p>

<p>例えば、Fastlane は「scan(xxx)」と書くだけでテストを実行できますが、xcodebuild で書く場合は「<code class="language-plaintext highlighter-rouge">xcodebuild -workspace ./xxx.xcworkspace -scheme xxx -derivedDataPath xxx ‘platform=iOS Simulator,id=xxx’ clean build test</code>」のように記述する必要があります。パッケージングやデプロイも自分で行うとなるとさらに面倒で、App Store Connect や Firebase API と連携しなければなりません。認証用のキーだけでも10行以上のコードを書く必要があります。</p>

<p><strong>Demo プロジェクトには Lane が3つだけあります：</strong></p>

<ul>
  <li>
    <p>run_all_tests: すべてのタイプのテストを実行する（Snapshot+Unit）</p>
  </li>
  <li>
    <p>run_unit_tests: 単体テストのみ実行（Unit）</p>
  </li>
  <li>
    <p>beta: Firebase App Distributionへのビルドとデプロイ</p>
  </li>
</ul>

<h4 id="fastlane--match">Fastlane — Match</h4>

<p>Demoプロジェクトの制限により、ここではMatchを使ってチームの開発・配布証明書を管理していませんが、チームのすべての開発・配布証明書を管理するためにMatchを使うことを推奨します。管理や一括更新が容易になります。</p>

<blockquote>
  <p><em>Matchを使えば、プロジェクトのセットアップ時に <code class="language-plaintext highlighter-rouge">match all</code> のようなコマンドで、開発に必要な証明書を一括インストールできます。</em></p>
</blockquote>

<ul>
  <li><strong>Fastlane Match は別のプライベートリポジトリで証明書と鍵を管理するため、GitHub Actions では SSH Agent を設定して別のプライベートリポジトリをクローンできるようにする必要があります。</strong><br />
（詳細は記事末の補足を参照してください）</li>
</ul>

<p><strong>[2026/02 Update] 参考資料 — iOS証明書、Fastlane Match、CI/CDの詳細補足:</strong></p>

<ul>
  <li>「 <a href="/posts/zrealm開発/ios-certificates-identifiers-profilesの関係-fastlane-matchで憑證管理とci-cdを効率化-823ac523ccc8/">iOS Certificates, Identifiers &amp; Profiles とは何かと Fastlane Match による証明書と CI/CD の一元管理メモ</a> 」</li>
</ul>

<p>— — —</p>

<h4 id="makefile">Makefile</h4>

<p><img src="/assets/4b001d2e8440/1*jYACUYFP3MkeHCgeUY7j3w.webp" alt="Makefile" loading="lazy" decoding="async" width="1200" height="423" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQyMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*jYACUYFP3MkeHCgeUY7j3w.png" /></p>

<p>Makefile</p>

<p>開発側と CI/CD が統一して Makefile を使ってコマンドを実行することで、同じ環境、パス、操作を簡単にパッケージ化できます。</p>

<blockquote>
  <p><em>よくあるケースとして、ローカルにインストールした <code class="language-plaintext highlighter-rouge">pod install</code> を使う人と、Bundler 管理の <code class="language-plaintext highlighter-rouge">bundle exec pod install</code> を使う人がいます。バージョンが異なると差異が生じる可能性があります。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>複雑すぎると感じたら使わなくても問題ありません。その場合は、Action Workflow の Step に直接実行したいコマンドを書くだけで大丈夫です。</em></strong></p>
</blockquote>

<p><strong>Makefile:</strong></p>

<div class="language-makefile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!make
</span><span class="nv">PRODUCT_FOLDER</span> <span class="o">=</span> ./Product/
<span class="nv">SHELL</span>         <span class="o">:=</span> /bin/zsh
<span class="nv">.DEFAULT_GOAL</span> <span class="o">:=</span> <span class="nb">install</span>
<span class="nv">MINT_DIRECTORY</span> <span class="o">:=</span> ./mint/

<span class="k">export </span><span class="nv">MINT_PATH</span><span class="o">=</span><span class="p">$(</span>MINT_DIRECTORY<span class="p">)</span>

<span class="c">## 👇 Help function
</span><span class="nl">.PHONY</span><span class="o">:</span> <span class="nf">help</span>
<span class="nl">help</span><span class="o">:</span>
 <span class="err">@echo</span> <span class="s2">""</span>
 <span class="nl">@echo "📖 利用可能なコマンド</span><span class="o">:</span><span class="nf">"</span>
 <span class="nl">@grep -E '^[a-zA-Z_-]+</span><span class="o">:</span><span class="nf">.*?</span><span class="c">##</span><span class="nf"> .*$$' $(MAKEFILE_LIST) </span>\\<span class="nf">| </span>\
<span class="nf">  awk 'BEGIN {FS = ":.*?</span><span class="c">##</span><span class="nf"> "}; {printf "  </span>\0<span class="nf">33[36m%-20s</span>\0<span class="nf">33[0m %s</span>\n<span class="nf">"</span><span class="p">,</span><span class="nf"> $$1</span><span class="p">,</span><span class="nf"> $$2}'</span>
 <span class="err">@echo</span> <span class="s2">""</span>

<span class="c">## Setup
</span><span class="nl">.PHONY</span><span class="o">:</span> <span class="nf">setup</span>
<span class="nl">setup</span><span class="o">:</span> <span class="nf">check-mint </span><span class="c">##</span><span class="nf"> Ruby と Mint の依存関係をインストール</span>
 <span class="err">@echo</span> <span class="s2">"🔨 Ruby の依存関係をインストール中..."</span>
 <span class="err">bundle</span> <span class="err">config</span> <span class="err">set</span> <span class="err">path</span> <span class="s1">'vendor/bundle'</span>
 <span class="err">bundle</span> <span class="err">install</span>
 <span class="err">@echo</span> <span class="s2">"🔨 Mint の依存関係をインストール中..."</span>
 <span class="err">mint</span> <span class="err">bootstrap</span>

<span class="c">## Install
</span><span class="nl">.PHONY</span><span class="o">:</span> <span class="nf">install</span>
<span class="nl">install</span><span class="o">:</span> <span class="nf">XcodeGen PodInstall </span><span class="c">##</span><span class="nf"> XcodeGen と CocoaPods のインストールを実行</span>

<span class="nl">.PHONY</span><span class="o">:</span> <span class="nf">XcodeGen</span>
<span class="nl">XcodeGen</span><span class="o">:</span> <span class="nf">check-mint </span><span class="c">##</span><span class="nf"> XcodeGen で .xcodeproj を生成</span>
 <span class="err">@echo</span> <span class="s2">"🔨 XcodeGen を実行中"</span>
 <span class="err">cd</span> <span class="err">$(PRODUCT_FOLDER)</span> <span class="err">&amp;&amp;</span> <span class="err">\</span>
 <span class="err">mint</span> <span class="err">run</span> <span class="err">yonaskolb/XcodeGen</span> <span class="err">--quiet</span>

<span class="nl">.PHONY</span><span class="o">:</span> <span class="nf">PodInstall</span>
<span class="nl">PodInstall</span><span class="o">:</span> <span class="c">##</span><span class="nf"> CocoaPods の依存関係をインストール</span>
 <span class="err">@echo</span> <span class="s2">"📦 CocoaPods の依存関係をインストール中..."</span>
 <span class="err">cd</span> <span class="err">$(PRODUCT_FOLDER)</span> <span class="err">&amp;&amp;</span> <span class="err">\</span>
 <span class="err">bundle</span> <span class="err">exec</span> <span class="err">pod</span> <span class="err">install</span>

<span class="c">### Mint
</span><span class="nl">check-mint</span><span class="o">:</span> <span class="nf">check-brew </span><span class="c">##</span><span class="nf"> Mint のインストールを確認し、なければ自動インストール</span>
 <span class="err">@if</span> <span class="err">!</span> <span class="err">command</span> <span class="err">-v</span> <span class="err">mint</span> <span class="err">&amp;&gt;</span> <span class="err">/dev/null;</span> <span class="err">then</span> <span class="err">\</span>
  <span class="err">echo</span> <span class="s2">"🔨 mint をインストールしています..."</span><span class="err">;</span> <span class="err">\</span>
  <span class="err">brew</span> <span class="err">install</span> <span class="err">mint;</span> <span class="err">\</span>
 <span class="err">fi</span>

<span class="c">### Brew
</span><span class="nl">check-brew</span><span class="o">:</span> <span class="c">##</span><span class="nf"> Homebrew のインストールを確認し、なければ自動インストール</span>
 <span class="err">@if</span> <span class="err">!</span> <span class="err">command</span> <span class="err">-v</span> <span class="err">brew</span> <span class="err">&amp;&gt;</span> <span class="err">/dev/null;</span> <span class="err">then</span> <span class="err">\</span>
  <span class="err">echo</span> <span class="s2">"🔨 Homebrew をインストールしています..."</span><span class="err">;</span> <span class="err">\</span>
  <span class="nl">/bin/bash -c "$$(curl -fsSL https</span><span class="o">:</span><span class="nf">//raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; </span>\
<span class="nf"> fi</span>

<span class="c">## Format only git swift files
</span><span class="nl">.PHONY</span><span class="o">:</span> <span class="nf">format</span>
<span class="nl">format</span><span class="o">:</span> <span class="nf">check-mint </span><span class="c">##</span><span class="nf"> Product/ 以下のすべての Swift ファイルをフォーマット</span>
 <span class="err">mint</span> <span class="err">run</span> <span class="err">swiftformat</span> <span class="err">$(PRODUCT_FOLDER)</span>
</code></pre></div></div>

<p>システム全体や他のプロジェクトへの影響を避けるために、Dependency パッケージ（例：mint、bundle など）のパスはできるだけプロジェクトディレクトリ内に指定し（さらに <code class="language-plaintext highlighter-rouge">.gitignore</code> で除外）しています。</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">├──</span> <span class="nt">mint</span> <span class="o">(</span><span class="nt">Mint</span> <span class="err">依存関係</span><span class="o">)</span>
<span class="err">│</span>   <span class="err">└──</span> <span class="nt">packages</span>
<span class="err">├──</span> <span class="nt">Product</span>
<span class="err">│</span>   <span class="err">├──</span> <span class="nt">app-ci-cd-github-actions-demo</span>
<span class="err">│</span>   <span class="err">├──</span> <span class="nt">app-ci-cd-github-actions-demo</span><span class="nc">.xcodeproj</span>
<span class="err">│</span>   <span class="err">├──</span> <span class="nt">app-ci-cd-github-actions-demo</span><span class="nc">.xcworkspace</span>
<span class="err">│</span>   <span class="err">├──</span> <span class="nt">app-ci-cd-github-actions-demoSnapshotTests</span>
<span class="err">│</span>   <span class="err">├──</span> <span class="nt">app-ci-cd-github-actions-demoTests</span>
<span class="err">│</span>   <span class="err">├──</span> <span class="nt">app-ci-cd-github-actions-demoUITests</span>
<span class="err">│</span>   <span class="err">├──</span> <span class="nt">fastlane</span>
<span class="err">│</span>   <span class="err">└──</span> <span class="nt">Pods</span> <span class="o">(</span><span class="nt">Cocoapods</span> <span class="err">依存関係</span><span class="o">)</span>
<span class="err">└──</span> <span class="nt">vendor</span> <span class="o">(</span><span class="nt">Bundle</span> <span class="err">依存関係</span><span class="o">)</span>
    <span class="err">└──</span> <span class="nt">bundle</span>
</code></pre></div></div>

<p><img src="/assets/4b001d2e8440/1*F1KFntT8bCZzyYm9JahiuA.webp" alt="make help" loading="lazy" decoding="async" width="449" height="142" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NDkiIGhlaWdodD0iMTQyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*F1KFntT8bCZzyYm9JahiuA.png" /></p>

<p>make help</p>

<div class="language-makefile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">help</span><span class="o">:</span> <span class="c">##</span><span class="nf"> ヘルプ表示</span>
	<span class="p">@</span><span class="nb">echo</span> <span class="s2">"Usage:"</span>
	<span class="p">@</span><span class="nb">echo</span> <span class="s2">"  make setup     # 環境セットアップ"</span>
	<span class="p">@</span><span class="nb">echo</span> <span class="s2">"  make lint      # コードの静的解析"</span>
	<span class="p">@</span><span class="nb">echo</span> <span class="s2">"  make test      # テスト実行"</span>
	<span class="p">@</span><span class="nb">echo</span> <span class="s2">"  make build     # アプリのビルド"</span>
	<span class="p">@</span><span class="nb">echo</span> <span class="s2">"  make deploy    # デプロイ実行"</span>
</code></pre></div></div>

<p><strong>Makefile を使った統一プロジェクトセットアップ手順：</strong></p>

<ol>
  <li>
    <p><code class="language-plaintext highlighter-rouge">git clone repo</code></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">cd ./repo</code></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">make setup</code><br />
必要なツールの依存関係をインストールします（<strong>brew</strong>、<strong>mint</strong>、<strong>bundle</strong>、xcodegen、swiftformat、…）</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">make install</code><br />
プロジェクトを生成します（pod install と xcodegen を実行）</p>
  </li>
  <li>
    <p>完了</p>
  </li>
  <li>
    <p>プロジェクトを開いて実行します</p>
  </li>
</ol>

<blockquote>
  <p><strong><em>CI/CDでも新人のオンボーディングでも、上記の手順でプロジェクトを構築します。</em></strong></p>
</blockquote>

<h3 id="本記事の-github-actions-cicd-事例">本記事の GitHub Actions CI/CD 事例</h3>

<p>本記事では、3つの GitHub Actions CI/CD ワークフロー構築例を紹介します。皆さんもこれらの手順を参考にして、自分のチームに合った CI/CD を構築できます。</p>

<ol>
  <li>
    <p>CI — プルリクエストで単体テストを実行する</p>
  </li>
  <li>
    <p>CD — Firebase App Distributionへのパッケージ化とデプロイ</p>
  </li>
  <li>
    <p>CI + CD — Nightly Buildでスナップショット＋単体テスト＋ビルド＋Firebase App Distributionへのデプロイを実行</p>
  </li>
</ol>

<blockquote>
  <p><em>デモの制限により、本記事では Firebase App Distribution へのパッケージ配布のみを扱います。Testflight や App Store への配布も同様の手順ですが、Fastlane のスクリプトが異なるだけですので、ご自身で応用してください。</em></p>
</blockquote>

<h3 id="ci--pull-requestでユニットテストを実行する">CI — Pull Requestでユニットテストを実行する</h3>

<h4 id="フロー">フロー</h4>

<p>Develop ブランチは <strong>直接プッシュできません</strong>。更新するには Pull Request を作成する必要があります。すべての Pull Request は <strong>レビュー承認と単体テストの合格が必要で、マージ可能</strong> です。新しいコミットがプッシュされると再度テストが実行されます。</p>

<h4 id="ci-testingyml">CI-Testing.yml</h4>

<p>Repo → Actions → New workflow → ワークフローを自分で設定する。</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ワークフロー(Action) 名称</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">CI-Testing</span>

<span class="c1"># Actions ログのタイトル名</span>
<span class="na">run-name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">[CI-Testing]</span><span class="nv"> </span><span class="s">${{</span><span class="nv"> </span><span class="s">github.event.pull_request.title</span><span class="nv"> </span><span class="se">\\</span><span class="s">|</span><span class="se">\\</span><span class="s">|</span><span class="nv"> </span><span class="s">github.ref</span><span class="nv"> </span><span class="s">}}"</span>

<span class="c1"># 同じ Concurrency Group に新しいジョブがある場合、実行中のジョブをキャンセルする</span>
<span class="c1"># 例えば Push Commit によってトリガーされたジョブがまだ実行中に、さらに Push Commit があった場合、前のジョブをキャンセルする</span>
<span class="na">concurrency</span><span class="pi">:</span>
  <span class="na">group</span><span class="pi">:</span> <span class="s">${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number \\|\\| github.ref }}</span>
  <span class="na">cancel-in-progress</span><span class="pi">:</span> <span class="kc">true</span>

<span class="c1"># トリガーイベント</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># PR イベント</span>
  <span class="na">pull_request</span><span class="pi">:</span>
    <span class="c1"># PR - オープン、再オープン、新しい Push Commit 時</span>
    <span class="na">types</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">opened</span><span class="pi">,</span> <span class="nv">synchronize</span><span class="pi">,</span> <span class="nv">reopened</span><span class="pi">]</span>
  <span class="c1"># 手動フォームトリガー</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>
    <span class="c1"># フォーム Inputs フィールド</span>
    <span class="na">inputs</span><span class="pi">:</span>
      <span class="c1"># 実行する Test Fastlane Lane</span>
      <span class="na">TEST_LANE</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">Test</span><span class="nv"> </span><span class="s">Lane'</span>
        <span class="na">default</span><span class="pi">:</span> <span class="s1">'</span><span class="s">run_unit_tests'</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">choice</span>
        <span class="na">options</span><span class="pi">:</span>
          <span class="pi">-</span> <span class="s">run_unit_tests</span>
          <span class="pi">-</span> <span class="s">run_all_tests</span>
  <span class="c1"># 他の Workflow から呼び出されるトリガー</span>
  <span class="c1"># Nightly Build で使用</span>
  <span class="na">workflow_call</span><span class="pi">:</span>
    <span class="c1"># フォーム Inputs フィールド</span>
    <span class="na">inputs</span><span class="pi">:</span>
      <span class="c1"># 実行する Test Fastlane Lane</span>
      <span class="na">TEST_LANE</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">Test</span><span class="nv"> </span><span class="s">Lane'</span>
        <span class="na">default</span><span class="pi">:</span> <span class="s1">'</span><span class="s">run_unit_tests'</span>
        <span class="c1"># workflow_call inputs は choice をサポートしない</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="na">BRANCH</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">Branch'</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
  
<span class="c1"># ジョブ</span>
<span class="c1"># ジョブは並行実行される</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="c1"># ジョブID</span>
  <span class="na">testing</span><span class="pi">:</span>
    <span class="c1"># ジョブ名 (省略可、ログ表示のため設定推奨)</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">Testing</span>
    
    <span class="c1"># Runner ラベル - GitHub Hosted Runner macos-15 を使用してジョブを実行</span>
    <span class="c1"># 注意：このプロジェクトは Public Repo のため無制限に無料利用可能</span>
    <span class="c1"># 注意：このプロジェクトは Public Repo のため無制限に無料利用可能</span>
    <span class="c1"># 注意：このプロジェクトは Public Repo のため無制限に無料利用可能</span>
    <span class="c1"># Private Repo の場合は従量課金制で、macOS マシンは最も高価（10倍）、10回実行で2,000分の無料上限に達する可能性あり</span>
    <span class="c1"># self-hosted Runner の利用を推奨</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">macos-15</span>

    <span class="c1"># 最大タイムアウト時間を設定し、異常時の無限待機を防止</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">30</span>

    <span class="c1"># zsh を使用</span>
    <span class="c1"># 省略可能、私は zsh を好むため設定、デフォルトは bash</span>
    <span class="na">defaults</span><span class="pi">:</span>
      <span class="na">run</span><span class="pi">:</span>
        <span class="na">shell</span><span class="pi">:</span> <span class="s">zsh {0}</span>
          
    <span class="c1"># ステップ</span>
    <span class="c1"># ステップは順番に実行される  </span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="c1"># git clone して現在のブランチをチェックアウト</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout repository</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v3</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="c1"># Git Large File Storage はテスト環境では不要</span>
          <span class="c1"># default: false</span>
          <span class="na">lfs</span><span class="pi">:</span> <span class="kc">false</span>
          
          <span class="c1"># 指定があればそのブランチをチェックアウト、なければデフォルト（現在のブランチ）</span>
          <span class="c1"># on: schedule イベントは main ブランチのみ実行可能なので、Nightly Build などで別ブランチを指定したい場合に利用</span>
          <span class="c1"># 例：on: schedule -&gt; main ブランチ、Nightly Build は master ブランチ</span>
          <span class="na">ref</span><span class="pi">:</span> <span class="s">${{ github.event.inputs.BRANCH \\|\\| '' }}</span>

      <span class="c1"># ========== 環境セットアップステップ ==========</span>
      
      <span class="c1"># プロジェクトで指定された XCode バージョンを読み取る</span>
      <span class="c1"># 後続で手動指定する XCode_x.x.x.app を使うため、xcversion は使用しない（非推奨で不安定のため）</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Read .xcode-version</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">read_xcode_version</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">XCODE_VERSION=$(cat .xcode-version)</span>
          <span class="s">echo "XCODE_VERSION</span><span class="err">:</span> <span class="s">${XCODE_VERSION}"</span>
          <span class="s">echo "xcode_version=${XCODE_VERSION}" &gt;&gt; $GITHUB_OUTPUT</span>

          <span class="s"># ここでグローバルに XCode バージョンを指定することも可能（後続で DEVELOPER_DIR 指定不要）</span>
          <span class="s"># ただし sudo 権限が必要、self-hosted runner の場合は runner 実行環境に sudo 権限があることを確認</span>
          <span class="s"># sudo xcode-select -s "/Applications/Xcode_${XCODE_VERSION}.app/Contents/Developer"</span>

      <span class="c1"># プロジェクトで指定された Ruby バージョンを読み取る</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Read .ruby-version</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">read_ruby_version</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">RUBY_VERSION=$(cat .ruby-version)</span>
          <span class="s">echo "RUBY_VERSION</span><span class="err">:</span> <span class="s">${RUBY_VERSION}"</span>
          <span class="s">echo "ruby_version=${RUBY_VERSION}" &gt;&gt; $GITHUB_OUTPUT</span>

      <span class="c1"># Runner の Ruby バージョンをプロジェクト指定バージョンに設定またはインストール</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Set up Ruby</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">ruby/setup-ruby@v1</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">ruby-version</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">steps.read_ruby_version.outputs.ruby_version</span><span class="nv"> </span><span class="s">}}"</span>

      <span class="c1"># 設定してもしなくてもよい。理由は self-hosted で複数 Runner を起動すると cocoapods repos の共有ディレクトリで競合が発生する可能性があるため</span>
      <span class="c1"># 問題は同時 pod install 時に cocoapods repos で競合が起きること（デフォルトは $HOME/.cocoapods/）</span>
      <span class="c1"># GitHub Hosted Runner ではこの設定は不要</span>
      <span class="c1"># - name: Change Cocoapods Repos Folder</span>
      <span class="c1">#   if: contains(runner.labels, 'self-hosted')</span>
      <span class="c1">#   run: \\|</span>
      <span class="c1">#     # 各 Runner ごとに独自の .cocoapods フォルダを作成しリソース競合を防止</span>
      <span class="c1">#     mkdir -p "$HOME/.cocoapods-${{ env.RUNNER_NAME }}/"</span>
      <span class="c1">#     export CP_HOME_DIR="$HOME/.cocoapods-${{ env.RUNNER_NAME }}"</span>
      <span class="c1">#     rm -f "$HOME/.cocoapods-${{ env.RUNNER_NAME }}/repos/cocoapods/.git/index.lock"</span>

      <span class="c1"># ========== キャッシュ設定ステップ ==========</span>
      <span class="c1"># 注意：self-hosted でもキャッシュはクラウドキャッシュで使用量が計算される</span>
      <span class="c1"># ルール：7日間ヒットしなければ自動削除、単一キャッシュ最大10GB、アクション成功時のみキャッシュ</span>
      <span class="c1"># Public Repo: 無料無制限</span>
      <span class="c1"># Private Repo: 5GB から</span>
      <span class="c1"># Self-hosted は独自に shell script でキャッシュ &amp; リストア戦略を作るか他ツール利用可能</span>
      
      <span class="c1"># Bundle キャッシュ (Gemfile)</span>
      <span class="c1"># Makefile で指定した Bundle インストール先 ./vendor に対応</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Cache Bundle</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/cache@v3</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">./vendor</span>
          <span class="na">key</span><span class="pi">:</span> <span class="s">${{ runner.os }}-bundle-${{ hashFiles('Gemfile.lock') }}</span>
          <span class="na">restore-keys</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">${{ runner.os }}-bundle-</span>

      <span class="c1"># CocoaPods キャッシュ (Podfile)</span>
      <span class="c1"># デフォルトはプロジェクトの ./Product/Pods 下</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Cache CocoaPods</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/cache@v3</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">./Product/Pods</span>
          <span class="na">key</span><span class="pi">:</span> <span class="s">${{ runner.os }}-cocoapods-${{ hashFiles('Product/Podfile.lock') }}</span>
          <span class="na">restore-keys</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">${{ runner.os }}-cocoapods-</span>

      <span class="c1"># Mint キャッシュ</span>
      <span class="c1"># Makefile で指定した Mint インストール先 ./mint に対応</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Cache Mint</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/cache@v3</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">./mint</span>
          <span class="na">key</span><span class="pi">:</span> <span class="s">${{ runner.os }}-mint-${{ hashFiles('Mintfile') }}</span>
          <span class="na">restore-keys</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">${{ runner.os }}-mint-</span>

      <span class="c1"># ====================</span>

      <span class="c1"># プロジェクトセットアップ &amp; 依存関係インストール</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup &amp; Install Dependency</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s"># Makefile にまとめた setup コマンドを実行、具体的には：</span>
          <span class="s"># brew install mint</span>
          <span class="s"># bundle config set path 'vendor/bundle'</span>
          <span class="s"># bundle install</span>
          <span class="s"># mint bootstrap</span>
          <span class="s"># ...</span>
          <span class="s"># その他 setup コマンド</span>
          <span class="s">make setup</span>

          <span class="s"># Makefile にまとめた install コマンドを実行、具体的には：</span>
          <span class="s"># mint run yonaskolb/XcodeGen --quiet</span>
          <span class="s"># bundle exec pod install</span>
          <span class="s"># ...</span>
          <span class="s"># その他 install コマンド</span>
          <span class="s">make install</span>

      <span class="c1"># Fastlane Unit テスト Lane を実行</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Run Tests</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">testing</span>
        <span class="c1"># 作業ディレクトリ指定、以降のコマンドで cd ./Product/ を省略可能</span>
        <span class="na">working-directory</span><span class="pi">:</span> <span class="s">./Product/</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="c1"># テストプラン、全テストか単体テストか</span>
          <span class="c1"># PR トリガーなら run_unit_tests、そうでなければ inputs.TEST_LANE の値（デフォルト run_all_tests）</span>
          <span class="na">TEST_LANE</span><span class="pi">:</span> <span class="s">${{ github.event_name == 'pull_request' &amp;&amp; 'run_unit_tests' \\|\\| github.event.inputs.TEST_LANE \\|\\| 'run_all_tests' }}</span>
          
          <span class="c1"># このジョブで使う XCode_x.x.x バージョンを指定</span>
          <span class="na">DEVELOPER_DIR</span><span class="pi">:</span> <span class="s2">"</span><span class="s">/Applications/Xcode_${{</span><span class="nv"> </span><span class="s">steps.read_xcode_version.outputs.xcode_version</span><span class="nv"> </span><span class="s">}}.app/Contents/Developer"</span>
          
          <span class="c1"># Repo -&gt; Settings -&gt; Actions secrets and variables -&gt; variables</span>
          <span class="c1"># 使用するシミュレーター名</span>
          <span class="na">SIMULATOR_NAME</span><span class="pi">:</span> <span class="s">${{ vars.SIMULATOR_NAME }}</span>
          <span class="c1"># シミュレーターの iOS バージョン</span>
          <span class="na">SIMULATOR_IOS_VERSION</span><span class="pi">:</span> <span class="s">${{ vars.SIMULATOR_IOS_VERSION }}</span>

          <span class="c1"># 現在の Runner 名称</span>
          <span class="na">RUNNER_NAME</span><span class="pi">:</span> <span class="s">${{ runner.name }}</span>
          
          <span class="c1"># XCodebuild コマンドのタイムアウト時間とリトライ回数を増加</span>
          <span class="c1"># マシン負荷が高いと3回で失敗することがあるため</span>
          <span class="na">FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT</span><span class="pi">:</span> <span class="m">60</span>
          <span class="na">FASTLANE_XCODEBUILD_SETTINGS_RETRIES</span><span class="pi">:</span> <span class="m">10</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>

          <span class="s"># self-hosted で同一マシンに複数 Runner を起動するとシミュレーターの競合が起きる（後で説明）</span>
          <span class="s"># 回避策としてシミュレーター名に Runner 名を入れて、Runner ごとに別のシミュレーターを使う</span>
          <span class="s"># 例：bundle exec fastlane run_unit_tests device:"${RUNNER_NAME} (${SIMULATOR_IOS_VERSION})"</span>
          <span class="s"># ここでは GitHub Hosted Runner を使うため問題なし、device:"${SIMULATOR_NAME} (${SIMULATOR_IOS_VERSION})" を直接使用</span>

          <span class="s"># エラーがあってもすぐに終了せず、すべての出力を temp/testing_output.txt に書き込む</span>
          <span class="s"># 後で内容を解析し、ビルド失敗かテスト失敗かを判断して PR にコメントを投稿</span>
          <span class="s">set +e</span>
          
          <span class="s"># EXIT_CODE は実行結果の終了コードを格納</span>
          <span class="s"># 0 = OK</span>
          <span class="s"># 1 = exit</span>
          <span class="s">EXIT_CODE=0</span>
          
          <span class="s"># すべての出力をファイルに書き込む</span>
          <span class="s">bundle exec fastlane ${TEST_LANE} device:"${SIMULATOR_NAME} (${SIMULATOR_IOS_VERSION})" \\| tee "$RUNNER_TEMP/testing_output.txt"</span>
          <span class="s"># 現在の EXIT_CODE が 0 なら、${PIPESTATUS[0]}（bundle exec fastlane の結果）を代入</span>
          <span class="s">[[ $EXIT_CODE -eq 0 ]] &amp;&amp; EXIT_CODE=${PIPESTATUS[0]}</span>

          <span class="s"># エラー時は即終了に戻す</span>
          <span class="s">set -e</span>

          <span class="s"># テスト出力をチェック</span>
          <span class="s"># 出力に "Error building" があれば is_build_error=true を Actions 環境変数に設定（ビルド失敗）</span>
          <span class="s"># 出力に "Tests have failed" があれば is_test_error=true を設定（テスト失敗）</span>
          
          <span class="s">if grep -q "Error building" "$RUNNER_TEMP/testing_output.txt"; then</span>
            <span class="s">echo "is_build_error=true" &gt;&gt; $GITHUB_OUTPUT</span>
            <span class="s">echo "❌ Detected Build Error"</span>
          <span class="s">elif grep -q "Tests have failed" "$RUNNER_TEMP/testing_output.txt"; then</span>
            <span class="s">echo "is_test_error=true" &gt;&gt; $GITHUB_OUTPUT</span>
            <span class="s">echo "❌ Detected Test Error"</span>
          <span class="s">fi</span>

          <span class="s"># Exit Code を復元</span>
          <span class="s">exit $EXIT_CODE</span>
          
      <span class="c1"># ========== 結果処理ステップ ==========</span>
      
      <span class="c1"># *.junit テストレポートを解析し、結果をマーク、PRならコメントも投稿</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Publish Test Report</span>
        <span class="c1"># 既存の .junit Parser Actions をそのまま利用：https://github.com/mikepenz/action-junit-report</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">mikepenz/action-junit-report@v5</span>
        <span class="c1"># if:</span>
        <span class="c1"># 前ステップ(Testing) 成功 または</span>
        <span class="c1"># 前ステップ(Testing) 失敗かつ is_test_error (ビルド失敗時は実行しない)</span>
        <span class="na">if</span><span class="pi">:</span> <span class="s">${{ (failure() &amp;&amp; steps.testing.outputs.is_test_error == 'true') \\|\\| success() }}</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">check_name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Testing</span><span class="nv"> </span><span class="s">Report"</span>
          <span class="na">comment</span><span class="pi">:</span> <span class="kc">true</span>
          <span class="na">updateComment</span><span class="pi">:</span> <span class="kc">false</span>
          <span class="na">require_tests</span><span class="pi">:</span> <span class="kc">true</span>
          <span class="na">detailed_summary</span><span class="pi">:</span> <span class="kc">true</span>
          <span class="na">report_paths</span><span class="pi">:</span> <span class="s2">"</span><span class="s">./Product/fastlane/test_output/*.junit"</span>

      <span class="c1"># ビルド失敗時のコメント投稿</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Build Failure Comment</span>
        <span class="c1"># if:</span>
        <span class="c1"># 前ステップ(Testing) 失敗かつ is_build_error かつ PR 番号あり</span>
        <span class="c1"># </span>
        <span class="na">if</span><span class="pi">:</span> <span class="s">${{ failure() &amp;&amp; steps.testing.outputs.is_build_error == 'true' &amp;&amp; github.event.pull_request.number }}</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/github-script@v6</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">action_url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">github.server_url</span><span class="nv"> </span><span class="s">}}/${{</span><span class="nv"> </span><span class="s">github.repository</span><span class="nv"> </span><span class="s">}}/actions/runs/${{</span><span class="nv"> </span><span class="s">github.run_id</span><span class="nv"> </span><span class="s">}}/attempts/${{</span><span class="nv"> </span><span class="s">github.run_attempt</span><span class="nv"> </span><span class="s">}}"</span>
        <span class="na">with</span><span class="pi">:</span>
            <span class="na">script</span><span class="pi">:</span> <span class="s">\\|</span>
              <span class="s">const action_url = process.env.action_url</span>
              <span class="s">const pullRequest = context.payload.pull_request \\|\\| {}</span>
              <span class="s">const commitSha = pullRequest.head?.sha \\|\\| context.sha</span>
              <span class="s">const creator = pullRequest.user?.login \\|\\| context.actor</span>
        
              <span class="s">const commentBody = [</span>
                <span class="s">`# プロジェクトまたはテストのビルド失敗 ❌`,</span>
                <span class="s">`Pull Request が正しくコンパイルおよびテスト実行できるかご確認ください。`,</span>
                <span class="s">``,</span>
                <span class="s">`🔗 **Action**</span><span class="err">:</span> <span class="pi">[</span><span class="nv">View Workflow Run</span><span class="pi">]</span><span class="s">(${action_url})`,</span>
                <span class="s">`📝 **Commit**</span><span class="err">:</span> <span class="s">${commitSha}`,</span>
                <span class="s">`👤 **Author**</span><span class="err">:</span> <span class="err">@</span><span class="s">${creator}`</span>
              <span class="s">].join('\n')</span>
        
              <span class="s">await github.rest.issues.createComment({</span>
                <span class="s">owner</span><span class="err">:</span> <span class="s">context.repo.owner,</span>
                <span class="s">repo</span><span class="err">:</span> <span class="s">context.repo.repo,</span>
                <span class="s">issue_number</span><span class="err">:</span> <span class="s">context.payload.pull_request.number,</span>
                <span class="s">body</span><span class="err">:</span> <span class="s">commentBody</span>
              <span class="s">})</span>
</code></pre></div></div>

<p><strong>技術的なポイント説明：</strong></p>

<ul>
  <li>
    <p>runs-on: self-hosted Runner の使用を推奨します。 <a href="https://docs.github.com/en/billing/managing-billing-for-your-products/about-billing-for-github-actions#per-minute-rates" target="_blank">GitHub Hosted Runner macOS は非常に高価です</a> 。</p>
  </li>
  <li>
    <p>手動で <code class="language-plaintext highlighter-rouge">.xcode-version</code> ファイルを読み取り、指定された XCode バージョンを取得し、XCode を指定するステップで <code class="language-plaintext highlighter-rouge">DEVELOPER_DIR</code> 環境変数を設定することで、Sudo を使わずに簡単に XCode を切り替えられます。</p>
  </li>
  <li>
    <p>Cache: 依存関係のインストール速度を向上させることができますが、self-hosted Runner でも GitHub Cloud Cache を使用するため、料金制限の対象となる点に注意が必要です。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">set +e</code> を使ってコマンドの失敗時にすぐに終了しないようにし、出力をすべてファイルに書き込み、そのファイルを読み込んで Build Failed か Test Failed かを判定します。これをしないとメッセージは一律 Test Failed になってしまいます。<br />
また、<code class="language-plaintext highlighter-rouge">Underlying Error: Unable to boot the Simulator.</code> のような他のエラー判定にも拡張可能です。例えば、シミュレーター起動失敗時は再試行を促すメッセージを表示します。</p>
  </li>
  <li>
    <p>Checkout Code は指定したブランチを受け入れ可能：<code class="language-plaintext highlighter-rouge">on: schedule</code> イベントは main（デフォルトブランチ）でのみトリガーされるため、スケジュールを他のブランチで実行したい場合は、ブランチを指定する必要があります。</p>
  </li>
  <li>
    <p>指定する .cocoapods Repo のパスは設定してもしなくてもよいです。以前、同じマシンの self-hosted Runner 2台が同時に pod install で詰まった原因は、たまたま両方が .cocoapods Repo に対して操作していて git lock が発生したためです。<br />
（ただし発生確率は非常に低いです）</p>
  </li>
  <li>
    <p><strong>もし Private Pods Repo があり、Clone 権限のために SSH Agent を設定する必要がある場合。</strong><br />
<strong>（詳細は文末の補足を参照してください）</strong></p>
  </li>
  <li>
    <p>リポジトリの Settings → Actions secrets and variables → variables に以下を追加してください：<br />
<code class="language-plaintext highlighter-rouge">SIMULATOR_IOS_VERSION</code> シミュレーターの iOS バージョン<br />
<code class="language-plaintext highlighter-rouge">SIMULATOR_NAME</code> シミュレーターの名前</p>
  </li>
</ul>

<p><img src="/assets/4b001d2e8440/1*Vj37P9vZ6KL5wWNvU3Cq3Q.webp" alt="" loading="lazy" decoding="async" width="1156" height="549" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTU2IiBoZWlnaHQ9IjU0OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*Vj37P9vZ6KL5wWNvU3Cq3Q.png" /></p>

<p><strong>Commit ファイルをリポジトリのメインブランチにプッシュし、手動で一度正しく動作するか検証します：</strong></p>

<p><img src="/assets/4b001d2e8440/1*tA2nKehTJ7aURSGgU7MM0g.webp" alt="" loading="lazy" decoding="async" width="1200" height="413" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQxMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*tA2nKehTJ7aURSGgU7MM0g.png" /></p>

<p><img src="/assets/4b001d2e8440/1*Qap3KmhIJrLov2O7GneV3w.webp" alt="" loading="lazy" decoding="async" width="1031" height="910" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDMxIiBoZWlnaHQ9IjkxMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*Qap3KmhIJrLov2O7GneV3w.png" /></p>

<p>正しく続けて設定してください。</p>

<h4 id="github-ワークフロー設定">GitHub ワークフロー設定</h4>

<p>Repo → Settins → Rules → Rulesets。</p>

<p><img src="/assets/4b001d2e8440/1*cf_M6NnakdcbzvC2VHSfpw.webp" alt="" loading="lazy" decoding="async" width="1202" height="964" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAyIiBoZWlnaHQ9Ijk2NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*cf_M6NnakdcbzvC2VHSfpw.png" /></p>

<ul>
  <li>
    <p>Ruleset Name: 規則名</p>
  </li>
  <li>
    <p>Enforcement status: 有効/無効 このルール制限</p>
  </li>
  <li>
    <p>Target branches: 対象のベースブランチ。Default Branch に設定すると、main や develop にマージしたいすべてのブランチがこのルールの対象になります。</p>
  </li>
  <li>
    <p>バイパスリスト：特定のユーザーやチームを指定して、この制限を免除できます</p>
  </li>
  <li>
    <p>ブランチルール:</p>
  </li>
</ul>

<p><img src="/assets/4b001d2e8440/1*Hzd9CCTsu18kyDR1goRWag.webp" alt="" loading="lazy" decoding="async" width="792" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3OTIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*Hzd9CCTsu18kyDR1goRWag.png" /></p>

<ul>
  <li>
    <p>Restrict deletions: ブランチの削除を禁止する</p>
  </li>
  <li>
    <p>Require a pull request before mergin: マージは必ずプルリクエスト経由で行う<br />
Required approvals: 承認が必要な人数を制限する</p>
  </li>
  <li>
    <p>Require status checks to pass: どのチェックがパスしないとマージできないかを制限する</p>
    <ul>
      <li>Add checks をクリックして <code class="language-plaintext highlighter-rouge">Testing</code> を入力し、GitHub Actions のマークが付いたものを選択します。<br />
<strong>ここで小さな問題があります。もし Suggestions に <code class="language-plaintext highlighter-rouge">Testing</code> が見つからない場合は、一度 Actions に戻って（PRを作成して試すなど）成功を1回トリガーする必要があります。そうするとここに表示されます。</strong></li>
    </ul>
  </li>
</ul>

<p><img src="/assets/4b001d2e8440/1*MRPwUEVVbbz8nH0sS2hFfQ.webp" alt="" loading="lazy" decoding="async" width="834" height="394" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzQiIGhlaWdodD0iMzk0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*MRPwUEVVbbz8nH0sS2hFfQ.png" /></p>

<ul>
  <li>Block force pushes: 強制プッシュをブロックする</li>
</ul>

<p>保存し、Enforcement status が Active であることを確認すると、ルールが有効になります。</p>

<p><strong>すべて設定が完了したら、PRを開いてテストしてみましょう：</strong></p>

<p><img src="/assets/4b001d2e8440/1*iPETBWx6Boq12rY1fHXmuQ.webp" alt="" loading="lazy" decoding="async" width="919" height="546" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTkiIGhlaWdodD0iNTQ2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*iPETBWx6Boq12rY1fHXmuQ.png" /></p>

<ul>
  <li>Checks に CI-Testing（<strong>必須</strong>）が表示され、マージがブロックされ、「少なくとも X 件の承認レビューが書き込み権限を持つレビュアーから必要です」と表示されている場合、設定は成功しています。</li>
</ul>

<p><strong>もしプロジェクトのビルドに失敗した場合 (Build Failed) はコメントします：</strong></p>

<p><img src="/assets/4b001d2e8440/1*4E35VRPo--pI8uqrR4UZNA.webp" alt="" loading="lazy" decoding="async" width="915" height="295" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTUiIGhlaWdodD0iMjk1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*4E35VRPo--pI8uqrR4UZNA.png" /></p>

<p><strong>プロジェクトのビルドは成功したがテストケースが失敗した場合（Test Failed）にコメント：</strong></p>

<p><img src="/assets/4b001d2e8440/1*wYFzsn5a_yvi8CbZxi-QdQ.webp" alt="" loading="lazy" decoding="async" width="921" height="389" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjEiIGhlaWdodD0iMzg5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*wYFzsn5a_yvi8CbZxi-QdQ.png" /></p>

<p><strong>プロジェクトのビルドが成功し、テストも成功した場合（Test Success）はコメントします：</strong></p>

<p><img src="/assets/4b001d2e8440/1*WqPK1629jYdYTEWCWBHWqg.webp" alt="" loading="lazy" decoding="async" width="915" height="321" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTUiIGhlaWdodD0iMzIxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*WqPK1629jYdYTEWCWBHWqg.png" /></p>

<p><strong>Review Approve + チェックテスト通過後：</strong></p>

<p><img src="/assets/4b001d2e8440/1*5gnQYdVAOtGR-bMK4ZrOhA.webp" alt="Demo PR" loading="lazy" decoding="async" width="911" height="566" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTEiIGhlaWdodD0iNTY2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*5gnQYdVAOtGR-bMK4ZrOhA.png" /></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/pull/11" target="_blank">Demo PR</a></p>

<p>これで PR をマージできます。</p>

<ul>
  <li>Pushで新しいコミットがあると、自動的にChecksテストが再実行されます。</li>
</ul>

<p><strong>完全なコード： <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/CI-Testing.yml" target="_blank">CI-Testing.yml</a></strong></p>

<p><strong>自動マージ:</strong></p>

<p>また、Repo Settings → General → Pull Request の中の以下を有効にすることもできます：</p>

<p><img src="/assets/4b001d2e8440/1*hl6mfqnnv_zAA3YVrI_M0w.webp" alt="" loading="lazy" decoding="async" width="856" height="257" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NTYiIGhlaWdodD0iMjU3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*hl6mfqnnv_zAA3YVrI_M0w.png" /></p>

<ul>
  <li>
    <p>Automatically delete head branches: PRマージ後に自動でブランチを削除する</p>
  </li>
  <li>
    <p>Allow Auto-merge: チェックが通過し、条件を満たした承認が得られると自動的にPRをマージします<br />
<strong>条件が設定されていて、現在の条件でまだマージできない場合にのみ Enable auto-merge ボタンが表示されます。</strong></p>
  </li>
</ul>

<p><img src="/assets/4b001d2e8440/1*gi0LaaMVXit-DGKnsxS1lQ.webp" alt="" loading="lazy" decoding="async" width="927" height="431" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjciIGhlaWdodD0iNDMxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*gi0LaaMVXit-DGKnsxS1lQ.png" /></p>

<h3 id="cd--firebase-app-distributionへのパッケージングとデプロイ">CD — Firebase App Distributionへのパッケージングとデプロイ</h3>

<h4 id="フロー-1">フロー</h4>

<p>GitHub Actions のフォームトリガーでビルドを実行し、バージョン番号やリリースノートを指定できます。ビルド完了後、自動的に Firebase App Distribution にアップロードされ、チームがダウンロードしてテストできます。</p>

<h4 id="cd-deployyml">CD-Deploy.yml</h4>

<p>Repo → Actions → New workflow → ワークフローを自分で設定する。</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ワークフロー(Action) 名称</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">CD-Deploy</span>

<span class="c1"># Actions ログのタイトル名</span>
<span class="na">run-name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">[CD-Deploy]</span><span class="nv"> </span><span class="s">${{</span><span class="nv"> </span><span class="s">github.ref</span><span class="nv"> </span><span class="s">}}"</span>

<span class="c1"># 同じ Concurrency Group 内で新しいジョブが開始された場合、実行中のジョブをキャンセルする</span>
<span class="c1"># 例：同じブランチのビルドジョブが繰り返しトリガーされた場合、前のジョブをキャンセルする</span>
<span class="na">concurrency</span><span class="pi">:</span>
  <span class="na">group</span><span class="pi">:</span> <span class="s">${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}</span>
  <span class="na">cancel-in-progress</span><span class="pi">:</span> <span class="kc">true</span>

<span class="c1"># トリガーイベント</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># 手動フォームトリガー</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>
    <span class="c1"># フォームの入力欄</span>
    <span class="na">inputs</span><span class="pi">:</span>
      <span class="c1"># アプリのバージョン番号</span>
      <span class="na">VERSION_NUMBER</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">アプリのバージョン番号（例:</span><span class="nv"> </span><span class="s">1.0.0）。空欄の場合はXcodeプロジェクトから自動検出します。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="c1"># アプリのビルド番号</span>
      <span class="na">BUILD_NUMBER</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">アプリのビルド番号（例:</span><span class="nv"> </span><span class="s">1）。空欄の場合はタイムスタンプを使用します。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="c1"># アプリのリリースノート</span>
      <span class="na">RELEASE_NOTE</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">デプロイのリリースノート。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
  <span class="c1"># 他のワークフローからの呼び出しトリガー</span>
  <span class="c1"># Nightly Build で使用</span>
  <span class="na">workflow_call</span><span class="pi">:</span>
    <span class="na">inputs</span><span class="pi">:</span>
      <span class="c1"># アプリのバージョン番号</span>
      <span class="na">VERSION_NUMBER</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">アプリのバージョン番号（例:</span><span class="nv"> </span><span class="s">1.0.0）。空欄の場合はXcodeプロジェクトから自動検出します。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="c1"># アプリのビルド番号</span>
      <span class="na">BUILD_NUMBER</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">アプリのビルド番号（例:</span><span class="nv"> </span><span class="s">1）。空欄の場合はタイムスタンプを使用します。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="c1"># アプリのリリースノート</span>
      <span class="na">RELEASE_NOTE</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">デプロイのリリースノート。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="na">BRANCH</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">ブランチ'</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>


<span class="c1"># グローバル静的変数の定義</span>
<span class="na">env</span><span class="pi">:</span>
  <span class="na">APP_STORE_CONNECT_API_KEY_FILE_NAME</span><span class="pi">:</span> <span class="s2">"</span><span class="s">app_store_connect_api_key.json"</span>

<span class="c1"># ジョブ定義</span>
<span class="c1"># ジョブは並行実行される</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="c1"># ジョブID</span>
  <span class="na">deploy</span><span class="pi">:</span>
    <span class="c1"># ジョブ名（省略可能、ログ表示用にあると見やすい）</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy - Firebase App Distribution</span>
    
    <span class="c1"># ランナーラベル - GitHubホストランナー macos-15 を使用してジョブを実行</span>
    <span class="c1"># 注意：このプロジェクトはパブリックリポジトリなので無制限に無料で使用可能</span>
    <span class="c1"># 注意：このプロジェクトはパブリックリポジトリなので無制限に無料で使用可能</span>
    <span class="c1"># 注意：このプロジェクトはパブリックリポジトリなので無制限に無料で使用可能</span>
    <span class="c1"># プライベートリポジトリの場合は従量課金で、macOSマシンは最も高価（10倍）、10回実行で2,000分の無料上限に達する可能性あり</span>
    <span class="c1"># self-hostedランナーの利用を推奨</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">macos-15</span>

    <span class="c1"># 最大タイムアウト時間の設定、異常時の無限待機防止</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">30</span>

    <span class="c1"># zshを使用</span>
    <span class="c1"># 省略可能、個人的にzshを使う習慣があるだけでデフォルトはbash</span>
    <span class="na">defaults</span><span class="pi">:</span>
      <span class="na">run</span><span class="pi">:</span>
        <span class="na">shell</span><span class="pi">:</span> <span class="s">zsh {0}</span>

    <span class="c1"># 作業ステップ</span>
    <span class="c1"># ステップは順番に実行される  </span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="c1"># git clone 現在のリポジトリ＆実行中のブランチをチェックアウト</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout repository</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v3</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="c1"># Git Large File Storage、テスト環境では不要</span>
          <span class="c1"># default: false</span>
          <span class="na">lfs</span><span class="pi">:</span> <span class="kc">false</span>
          
          <span class="c1"># 指定があれば指定ブランチをチェックアウト、なければデフォルト（現在のブランチ）</span>
          <span class="c1"># on: schedule イベントは main ブランチでしか実行できないため、Nightly Build などをする場合はブランチ指定が必要</span>
          <span class="c1"># 例：on: schedule -&gt; main ブランチ、Nightly Build は master ブランチ</span>
          <span class="na">ref</span><span class="pi">:</span> <span class="s">${{ github.event.inputs.BRANCH \\|\\| '' }}</span>

      <span class="c1"># ========== 証明書関連ステップ ==========</span>
      
      <span class="c1"># Fastlane - Match を使って開発証明書を管理し、Lane内で直接matchを実行して設定する方法を推奨</span>
      <span class="c1"># Match は別のプライベートリポジトリで証明書を管理するが、SSH Agentの設定が必要でないとprivate repoのgit clone権限がない</span>
      <span class="c1"># ref: https://stackoverflow.com/questions/57612428/cloning-private-github-repository-within-organisation-in-actions</span>
      <span class="c1">#</span>
      <span class="c1">#</span>
      <span class="c1"># --- Fastlane - Match を使わずに証明書を直接ダウンロード＆インポートする方法 ---</span>
      <span class="c1"># ref: https://docs.github.com/en/actions/how-tos/use-cases-and-examples/deploying/installing-an-apple-certificate-on-macos-runners-for-xcode-development</span>
      <span class="c1">#</span>
      <span class="c1"># GitHub Actions Secret はファイルを保存できないため、すべての証明書ファイルはBase64エンコードされた文字列としてSecretに保存</span>
      <span class="c1"># GitHub Actionsステップ内で動的に読み込み、一時ファイルに書き込み、正しい場所に移動してシステムに認識させる</span>
      <span class="c1"># 詳細は記事参照</span>
      <span class="c1">#</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install the Apple certificate and provisioning profile</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">BUILD_CERTIFICATE_BASE64</span><span class="pi">:</span> <span class="s">${{ secrets.BUILD_CERTIFICATE_BASE64 }}</span>
          <span class="na">P12_PASSWORD</span><span class="pi">:</span> <span class="s">${{ secrets.BUILD_CERTIFICATE_P12_PASSWORD }}</span>
          <span class="na">BUILD_PROVISION_PROFILE_BASE64</span><span class="pi">:</span> <span class="s">${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}</span>
          <span class="c1"># GitHub Hosted Runner はカスタム文字列</span>
          <span class="c1"># Self-hosted Runner はマシンのログインパスワード</span>
          <span class="na">KEYCHAIN_PASSWORD</span><span class="pi">:</span> <span class="s">${{ secrets.KEYCHAIN_PASSWORD }}</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s"># 変数作成</span>
          <span class="s">CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12</span>
          <span class="s">PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision</span>
          <span class="s">KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db</span>

          <span class="s"># Secretから証明書とプロビジョニングプロファイルをインポート</span>
          <span class="s">echo -n "$BUILD_CERTIFICATE_BASE64" \\| base64 --decode -o $CERTIFICATE_PATH</span>
          <span class="s">echo -n "$BUILD_PROVISION_PROFILE_BASE64" \\| base64 --decode -o $PP_PATH</span>

          <span class="s"># 一時キーチェーン作成</span>
          <span class="s">security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH</span>
          <span class="s">security set-keychain-settings -lut 21600 $KEYCHAIN_PATH</span>
          <span class="s">security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH</span>

          <span class="s"># 証明書をキーチェーンにインポート</span>
          <span class="s">security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH</span>
          <span class="s">security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH</span>
          <span class="s">security list-keychain -d user -s $KEYCHAIN_PATH</span>

          <span class="s"># プロビジョニングプロファイル適用</span>
          <span class="s">mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles</span>
          <span class="s">cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles</span>

      <span class="c1"># App Store Connect API Fastlane JSON Key</span>
      <span class="c1"># ビルド環境ではほぼ必須のApp Store Connect API Fastlane JSON Key (.json)</span>
      <span class="c1"># フォーマット: .json 内容フォーマット：https://docs.fastlane.tools/app-store-connect-api/</span>
      <span class="c1"># App Store Connect APIの.p8キーを含む</span>
      <span class="c1"># 後続でFastlaneに渡し、TestflightやApp Store APIのアップロードに使用</span>
      <span class="c1">#</span>
      <span class="c1"># GitHub Actions Secret はファイル保存不可のため、すべてBase64エンコードされた文字列としてSecretに保存</span>
      <span class="c1"># ステップ内で動的に読み込み、一時ファイルに書き込み他のステップで参照</span>
      <span class="c1"># 詳細は記事参照</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Read and Write Apple Store Connect API Key to Temp</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">APP_STORE_CONNECT_API_KEY_BASE64</span><span class="pi">:</span> <span class="s">${{ secrets.APP_STORE_CONNECT_API_KEY_BASE64 }}</span>
          <span class="na">APP_STORE_CONNECT_API_KEY_PATH</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">runner.temp</span><span class="nv"> </span><span class="s">}}/${{</span><span class="nv"> </span><span class="s">env.APP_STORE_CONNECT_API_KEY_FILE_NAME</span><span class="nv"> </span><span class="s">}}"</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s"># SecretからAPIキーをインポート</span>
          <span class="s">echo -n "$APP_STORE_CONNECT_API_KEY_BASE64" \\| base64 --decode -o $APP_STORE_CONNECT_API_KEY_PATH</span>

      <span class="c1"># ========== 環境セットアップステップ ==========</span>
      
      <span class="c1"># プロジェクト指定のXCodeバージョンを読み込み</span>
      <span class="c1"># 後続で手動指定した XCode_x.x.x.app を使用</span>
      <span class="c1"># xcversionは非推奨で不安定なため使用しない</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Read .xcode-version</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">read_xcode_version</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">XCODE_VERSION=$(cat .xcode-version)</span>
          <span class="s">echo "XCODE_VERSION</span><span class="err">:</span> <span class="s">${XCODE_VERSION}"</span>
          <span class="s">echo "xcode_version=${XCODE_VERSION}" &gt;&gt; $GITHUB_OUTPUT</span>

          <span class="s"># ここでグローバルXCodeバージョンを指定することも可能（後続でDEVELOPER_DIR指定不要）</span>
          <span class="s"># ただしsudo権限が必要。self-hosted runnerの場合はランナー実行環境にsudo権限があることを確認</span>
          <span class="s"># sudo xcode-select -s "/Applications/Xcode_${XCODE_VERSION}.app/Contents/Developer"</span>

      <span class="c1"># プロジェクト指定のRubyバージョンを読み込み</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Read .ruby-version</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">read_ruby_version</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">RUBY_VERSION=$(cat .ruby-version)</span>
          <span class="s">echo "RUBY_VERSION</span><span class="err">:</span> <span class="s">${RUBY_VERSION}"</span>
          <span class="s">echo "ruby_version=${RUBY_VERSION}" &gt;&gt; $GITHUB_OUTPUT</span>

      <span class="c1"># ランナーのRubyバージョンをプロジェクト指定バージョンにセットアップ</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Set up Ruby</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">ruby/setup-ruby@v1</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">ruby-version</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">steps.read_ruby_version.outputs.ruby_version</span><span class="nv"> </span><span class="s">}}"</span>

      <span class="c1"># 設定してもしなくてもよい。以前self-hostedで複数runnerを起動した際、cocoapods reposが共有ディレクトリのため</span>
      <span class="c1"># 同時にpod installしたときにcocoapods reposの競合が起きることがあった（デフォルトは$HOME/.cocoapods/）</span>
      <span class="c1"># GitHub Hosted Runnerでは不要</span>
      <span class="c1"># - name: Change Cocoapods Repos Folder</span>
      <span class="c1">#   if: contains(runner.labels, 'self-hosted')</span>
      <span class="c1">#   run: \\|</span>
      <span class="c1">#     # 各ランナーごとに独自の.cocoapodsフォルダを使い、リソース競合を防止</span>
      <span class="c1">#     mkdir -p "$HOME/.cocoapods-${{ env.RUNNER_NAME }}/"</span>
      <span class="c1">#     export CP_HOME_DIR="$HOME/.cocoapods-${{ env.RUNNER_NAME }}"</span>
      <span class="c1">#     rm -f "$HOME/.cocoapods-${{ env.RUNNER_NAME }}/repos/cocoapods/.git/index.lock"</span>

      <span class="c1"># ========== キャッシュ設定ステップ ==========</span>
      <span class="c1"># 注意：self-hostedでもキャッシュはクラウドキャッシュで容量計算される</span>
      <span class="c1"># ルール：7日間未ヒットで自動削除、単一キャッシュ最大10GB、アクション成功時のみキャッシュ</span>
      <span class="c1"># パブリックリポジトリ：無料無制限</span>
      <span class="c1"># プライベートリポジトリ：5GBから課金</span>
      <span class="c1"># Self-hostedは独自にshellスクリプトでキャッシュ＆リストア戦略を作るか他ツール利用可能</span>
      
      <span class="c1"># Bundle Cache (Gemfile)</span>
      <span class="c1"># Makefileで指定したBundleインストールパス ./vendor に対応</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Cache Bundle</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/cache@v3</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">./vendor</span>
          <span class="na">key</span><span class="pi">:</span> <span class="s">${{ runner.os }}-bundle-${{ hashFiles('Gemfile.lock') }}</span>
          <span class="na">restore-keys</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">${{ runner.os }}-bundle-</span>

      <span class="c1"># CocoaPods Cache (Podfile)</span>
      <span class="c1"># デフォルトはプロジェクト内の ./Product/Pods</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Cache CocoaPods</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/cache@v3</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">./Product/Pods</span>
          <span class="na">key</span><span class="pi">:</span> <span class="s">${{ runner.os }}-cocoapods-${{ hashFiles('Product/Podfile.lock') }}</span>
          <span class="na">restore-keys</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">${{ runner.os }}-cocoapods-</span>

      <span class="c1"># Mint cache</span>
      <span class="c1"># Makefileで指定したMintインストールパス ./mint に対応</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Cache Mint</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/cache@v3</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">./mint</span>
          <span class="na">key</span><span class="pi">:</span> <span class="s">${{ runner.os }}-mint-${{ hashFiles('Mintfile') }}</span>
          <span class="na">restore-keys</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">${{ runner.os }}-mint-</span>

      <span class="c1"># ====================</span>

      <span class="c1"># プロジェクトセットアップ＆依存関係インストール</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup &amp; Install Dependency</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s"># Makefileでラップされたsetupコマンドを実行。内容はおおよそ：</span>
          <span class="s"># brew install mint</span>
          <span class="s"># bundle config set path 'vendor/bundle'</span>
          <span class="s"># bundle install</span>
          <span class="s"># mint bootstrap</span>
          <span class="s"># ...</span>
          <span class="s"># その他setupコマンド</span>
          <span class="s">make setup</span>

          <span class="s"># Makefileでラップされたinstallコマンドを実行。内容はおおよそ：</span>
          <span class="s"># mint run yonaskolb/XcodeGen --quiet</span>
          <span class="s"># bundle exec pod install</span>
          <span class="s"># ...</span>
          <span class="s"># その他installコマンド</span>
          <span class="s">make install</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy Beta</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">deploy</span>
        <span class="c1"># 作業ディレクトリ指定。以降のコマンドでcd ./Product/不要</span>
        <span class="na">working-directory</span><span class="pi">:</span> <span class="s">./Product/</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="c1"># ビルド入力パラメータ</span>
          <span class="na">VERSION_NUMBER</span><span class="pi">:</span> <span class="s">${{ inputs.VERSION_NUMBER \\|\\| '' }}</span>
          <span class="na">BUILD_NUMBER</span><span class="pi">:</span> <span class="s">${{ inputs.BUILD_NUMBER \\|\\| '' }}</span>
          <span class="na">RELEASE_NOTE</span><span class="pi">:</span> <span class="s">${{ inputs.RELEASE_NOTE \\|\\| '' }}</span>
          <span class="na">AUTHOR</span><span class="pi">:</span> <span class="s">${{ github.actor }}</span>

          <span class="c1"># リポジトリ -&gt; 設定 -&gt; Actions secrets and variables -&gt; secrets</span>
          <span class="c1"># Firebase CLIトークン（取得方法は記事参照）</span>
          <span class="na">FIREBASE_CLI_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.FIREBASE_CLI_TOKEN }}</span>
          <span class="c1"># Apple Developer Program Team ID</span>
          <span class="na">TEAM_ID</span><span class="pi">:</span> <span class="s">${{ secrets.TEAM_ID }}</span>
                    
          <span class="c1"># このジョブで使用するXCode_x.x.xバージョン指定</span>
          <span class="na">DEVELOPER_DIR</span><span class="pi">:</span> <span class="s2">"</span><span class="s">/Applications/Xcode_${{</span><span class="nv"> </span><span class="s">steps.read_xcode_version.outputs.xcode_version</span><span class="nv"> </span><span class="s">}}.app/Contents/Developer"</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s"># 現在のタイムスタンプ取得</span>
          <span class="s">BUILD_TIMESTAMP=$(date +'%Y%m%d%H%M%S')</span>

          <span class="s"># BUILD_NUMBERが空ならタイムスタンプをApp Build Numberに使用</span>
          <span class="s">BUILD_NUMBER="${BUILD_NUMBER:-$BUILD_TIMESTAMP}"</span>
  
          <span class="s">ID="${{ github.run_id }}"</span>
          <span class="s">COMMIT_SHA="${{ github.sha }}"</span>
          <span class="s">BRANCH_NAME="${{ github.ref_name }}"</span>
          <span class="s">AUTHOR="${{ env.AUTHOR }}"</span>

          <span class="s"># リリースノートを組み立て</span>
          <span class="s">RELEASE_NOTE="${{ env.RELEASE_NOTE }}</span>
          <span class="s">ID</span><span class="err">:</span> <span class="s">${ID}</span>
          <span class="s">Commit SHA</span><span class="err">:</span> <span class="s">${COMMIT_SHA}</span>
          <span class="s">Branch</span><span class="err">:</span> <span class="s">${BRANCH_NAME}</span>
          <span class="s">Author</span><span class="err">:</span> <span class="s">${AUTHOR}</span>
          <span class="s">"</span>

          <span class="s"># Fastlaneでビルド＆デプロイLaneを実行</span>
          <span class="s">bundle exec fastlane beta release_notes:"${RELEASE_NOTE}" version_number:"${VERSION_NUMBER}" build_number:"${BUILD_NUMBER}"</span>

      <span class="c1"># GitHub Actions推奨のself-hostedセキュリティ設定：</span>
      <span class="c1"># ref: https://docs.github.com/en/actions/how-tos/use-cases-and-examples/deploying/installing-an-apple-certificate-on-macos-runners-for-xcode-development#required-clean-up-on-self-hosted-runners</span>
      <span class="c1"># 「Install the Apple certificate and provisioning profile」ステップに対応</span>
      <span class="c1"># マシンにダウンロードしたキー証明書を削除するため</span>
      <span class="c1"># Matchを使っている場合はMatchのクリーン処理に書き換えが必要</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Clean up keychain and provisioning profile</span>
        <span class="na">if</span><span class="pi">:</span> <span class="s">${{ always() &amp;&amp; contains(runner.labels, 'self-hosted') }}</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">security delete-keychain $RUNNER_TEMP/app-signing.keychain-db</span>
          <span class="s">rm ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.mobileprovision</span>
</code></pre></div></div>

<ul>
  <li>リポジトリの Settings → Actions secrets and variables → secrets に <code class="language-plaintext highlighter-rouge">TEAM_ID</code> という変数を追加し、内容に Apple Developer Team ID の文字列を設定してください。</li>
</ul>

<p><img src="/assets/4b001d2e8440/1*dxdmT_N_w_VUd56f6GRLSQ.webp" alt="" loading="lazy" decoding="async" width="1181" height="498" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTgxIiBoZWlnaHQ9IjQ5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*dxdmT_N_w_VUd56f6GRLSQ.png" /></p>

<p><strong>Commit ファイルをリポジトリのメインブランチにプッシュして、ビルド機能をテストします：</strong></p>

<p><img src="/assets/4b001d2e8440/1*Z_UAfWAsJSIoWxeTRMvtDQ.webp" alt="" loading="lazy" decoding="async" width="1072" height="685" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDcyIiBoZWlnaHQ9IjY4NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*Z_UAfWAsJSIoWxeTRMvtDQ.png" /></p>

<blockquote>
  <p><em>他のブランチでこの Action を使用する場合は、まずメインブランチの CD-Deploy.yml ファイルをマージする必要があります。</em></p>
</blockquote>

<p><strong>タスクの完了を待つ：</strong></p>

<p><img src="/assets/4b001d2e8440/1*Q-c2IUlJpssooiqcqcm_Bg.webp" alt="" loading="lazy" decoding="async" width="1386" height="1288" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzg2IiBoZWlnaHQ9IjEyODgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/4b001d2e8440/1*Q-c2IUlJpssooiqcqcm_Bg.png" /></p>

<p><img src="/assets/4b001d2e8440/1*W8PBkatfsITMDFSlp7xpjg.webp" alt="Demo" loading="lazy" decoding="async" width="1200" height="975" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk3NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*W8PBkatfsITMDFSlp7xpjg.png" /></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/actions/runs/16114046420" target="_blank">Demo</a></p>

<blockquote>
  <p><strong><em>ビルド＋デプロイ成功 ✅</em></strong></p>
</blockquote>

<p><strong>完全なコード： <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/CD-Deploy.yml" target="_blank">CD-Deploy.yml</a></strong></p>

<h4 id="技術的詳細--firebase-cli-トークン取得設定">技術的詳細 — Firebase CLI トークン取得＆設定</h4>

<p><a href="https://firebase.google.com/docs/cli?hl=zh-tw#install-cli-mac-linux" target="_blank">Firbase公式ドキュメントの手順</a> に従って：</p>

<p>まず Firebase CLI ツールをインストールします：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-sL</span> https://firebase.tools <span class="se">\\</span>| bash
</code></pre></div></div>

<p>実行：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>firebase login:ci
</code></pre></div></div>

<p>ログインと認証の完了：</p>

<p><img src="/assets/4b001d2e8440/1*Jex5aYzRSs7Trfx6z_e1Aw.webp" alt="" loading="lazy" decoding="async" width="1063" height="701" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDYzIiBoZWlnaHQ9IjcwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*Jex5aYzRSs7Trfx6z_e1Aw.png" /></p>

<p><img src="/assets/4b001d2e8440/1*S-1ckn9WC6j0DIqZGSdUUg.webp" alt="" loading="lazy" decoding="async" width="427" height="213" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MjciIGhlaWdodD0iMjEzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*S-1ckn9WC6j0DIqZGSdUUg.png" /></p>

<p>Terminal に戻り、Firebase CLI トークンをコピーします:</p>

<p><img src="/assets/4b001d2e8440/1*sa_h8L08JbeC2nA0kACQtQ.webp" alt="" loading="lazy" decoding="async" width="682" height="483" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2ODIiIGhlaWdodD0iNDgzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*sa_h8L08JbeC2nA0kACQtQ.png" /></p>

<p>Repo → Settings → Secrets and variables → Actions → 新しい Secret を追加：<code class="language-plaintext highlighter-rouge">FIREBASE_CLI_TOKEN</code> に Firebase CLI トークンを貼り付けます。</p>

<p><img src="/assets/4b001d2e8440/1*Lc6yGPu7L_0z6u1HH2PB5A.webp" alt="" loading="lazy" decoding="async" width="1171" height="515" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTcxIiBoZWlnaHQ9IjUxNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*Lc6yGPu7L_0z6u1HH2PB5A.png" /></p>

<blockquote>
  <p><strong><em>このトークン = あなたのログインID</em></strong> <em>です。大切に保管してください。アカウントを退職する際には必ず更新が必要です。</em></p>
</blockquote>

<h4 id="技術的詳細--apple証明書とプロビジョニングプロファイルのインストール">技術的詳細 — Apple証明書とプロビジョニングプロファイルのインストール</h4>

<p>開発証明書を Runner にインポートする手順の詳細補足。</p>

<p>GitHub Actions の Secret ではファイルを保存できないため、すべての証明書ファイルは事前に Base64 エンコードされた文字列として Secrets に保存します。GitHub Actions のステップ内で動的に読み込み、一時ファイルに書き出してから正しい場所に移動し、システムが使用できるようにします。</p>

<p><strong>Developmentビルドには2つの鍵証明書が必要です：</strong></p>

<ul>
  <li>
    <p><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">プロビジョニングプロファイル (.mobileprovision)</a></p>
  </li>
  <li>
    <p><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">開発証明書 (.p12)</a></p>
  </li>
</ul>

<p><img src="/assets/4b001d2e8440/1*WXqqnErto3nn8rnNg6TXgw.webp" alt="cicd.mobileprovision" loading="lazy" decoding="async" width="1117" height="616" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTE3IiBoZWlnaHQ9IjYxNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*WXqqnErto3nn8rnNg6TXgw.png" /></p>

<p>cicd.mobileprovision</p>

<p><img src="/assets/4b001d2e8440/1*RkeZ1PkXeY9Nt1kSRJKEQw.webp" alt="development.cer" loading="lazy" decoding="async" width="1078" height="738" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDc4IiBoZWlnaHQ9IjczOCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*RkeZ1PkXeY9Nt1kSRJKEQw.png" /></p>

<p>development.cer</p>

<p><a href="https://developer.apple.com/account/resources/certificates/list" target="_blank">Apple Developer</a> からダウンロードした証明書は .cer 形式ですが、必要なのは .p12 形式です。まずダウンロードした .cer をダブルクリックしてキーチェーンにインストールし、キーチェーンを開いて該当の証明書を右クリックしてエクスポートしてください。</p>

<p><img src="/assets/4b001d2e8440/1*HJMxwM3IDjxT-UGqnoUtWw.webp" alt="" loading="lazy" decoding="async" width="924" height="526" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjQiIGhlaWdodD0iNTI2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*HJMxwM3IDjxT-UGqnoUtWw.png" /></p>

<p>ファイル名：cicd.p12、フォーマット .p12</p>

<p>P12 キーのパスワード：安全なカスタム文字列を入力してください（例は良くない例で、<code class="language-plaintext highlighter-rouge">123456</code> を使用しています）</p>

<p><img src="/assets/4b001d2e8440/1*tyH0XqDVPGPWFJPL4dxksw.webp" alt="" loading="lazy" decoding="async" width="572" height="356" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NzIiIGhlaWdodD0iMzU2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*tyH0XqDVPGPWFJPL4dxksw.png" /></p>

<p><img src="/assets/4b001d2e8440/1*qKeZWel3w_5wW7meMtHmLA.webp" alt="" loading="lazy" decoding="async" width="556" height="381" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTYiIGhlaWdodD0iMzgxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*qKeZWel3w_5wW7meMtHmLA.png" /></p>

<p><strong>現在二つのファイル：</strong> cicd.p12、cicd.mobileprovision が準備できました</p>

<p><strong>BASE64形式の文字列に変換してRepoのSecretsに保存：</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">base64</span> <span class="nt">-i</span> cicd.mobileprovision <span class="se">\\</span>| pbcopy
</code></pre></div></div>

<p>#（コマンドのコメントは翻訳不要のためそのままにします）</p>

<p>Repo → Settings → Secrets and variables → Actions → 新しい Secret を追加：<code class="language-plaintext highlighter-rouge">BUILD_PROVISION_PROFILE_BASE64</code> そして上記の内容を貼り付けます。</p>

<p>-</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">base64</span> <span class="nt">-i</span> cicd.p12 <span class="se">\\</span>| pbcopy
</code></pre></div></div>

<p>#（注釈はコード内にありませんので、翻訳不要です）</p>

<p>Repo → Settings → Secrets and variables → Actions → 新しい Secret を追加：<code class="language-plaintext highlighter-rouge">BUILD_CERTIFICATE_BASE64</code> に上記の内容を貼り付けます。</p>

<p>-</p>

<p>Repo → Settings → Secrets and variables → Actions → 新しい Secret を追加：<code class="language-plaintext highlighter-rouge">P12_PASSWORD</code> 内容はエクスポートした P12 キーのパスワードです。</p>

<p>-
Repo → Settings → Secrets and variables → Actions → で新しい Secret: <code class="language-plaintext highlighter-rouge">KEYCHAIN_PASSWORD</code> を追加します。<br />
GitHub Hosted Runner の場合は任意の文字列を入力してください。<br />
<strong>Self-hosted Runner の場合は macOS Runner ユーザーのログインパスワードを入力します。</strong></p>

<p><img src="/assets/4b001d2e8440/1*JZCkFUJCQsggqYtW8acjTw.webp" alt="" loading="lazy" decoding="async" width="1088" height="493" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDg4IiBoZWlnaHQ9IjQ5MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*JZCkFUJCQsggqYtW8acjTw.png" /></p>

<h4 id="技術的詳細--app-store-connect-apiキー">技術的詳細 — App Store Connect APIキー</h4>

<p>Fastlane で App Store や Testflight にパッケージとデプロイする際に必要な <a href="https://docs.fastlane.tools/app-store-connect-api/" target="_blank">.json キー</a> は、GitHub Actions の Secrets が文字列しか保存できずファイルは保存できない制限があるため、キーの内容を Base64 文字列に変換し、GitHub Actions のステップ内で動的に読み出して一時ファイルに書き込み、そのファイルパスを Fastlane に渡して使用します。</p>

<p><strong>まずは <a href="/posts/zrealm-dev/app-store-connect-api-customer-reviews-管理を強化-in-app-purchases-subscriptionsも対応-f1365e51902c/">App Store Connect で App Store Connect API Key (.p8) を作成＆ダウンロード</a> してください：</strong></p>

<pre><code class="language-vbnet">-----BEGIN PRIVATE KEY-----
sss
axzzvcxz
zxzvzcxv
vzxcvzxvczxcvz
-----END PRIVATE KEY-----
</code></pre>

<p><code class="language-plaintext highlighter-rouge">app_store_connect_api.json</code> ファイルを新規作成する（<a href="https://docs.fastlane.tools/app-store-connect-api/" target="_blank">内容参考</a>）：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">{</span>
  <span class="s2">"key_id"</span>: <span class="s2">"App Store Connect に記載されている Key ID"</span>,
  <span class="s2">"issuer_id"</span>: <span class="s2">"App Store Connect に記載されている Issuer ID"</span>,
  <span class="s2">"key"</span>: <span class="s2">"-----BEGIN PRIVATE KEY-----改行は必ず</span><span class="se">\n</span><span class="s2">に変更してください-----END PRIVATE KEY-----"</span>,
  <span class="s2">"duration"</span>: 1200, <span class="c"># 任意 (最大1200)</span>
  <span class="s2">"in_house"</span>: <span class="nb">false</span> <span class="c"># 任意ですが、match/sigh を使用する場合は必要になることがあります</span>
<span class="o">}</span>
</code></pre></div></div>

<p>ファイルを保存した後に実行：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">base64</span> <span class="nt">-i</span> app_store_connect_api.json <span class="se">\\</span>| pbcopy
</code></pre></div></div>

<h1 id="app_store_connect_apijsonをbase64エンコードしてクリップボードにコピーするコマンド">「app_store_connect_api.json」をBase64エンコードしてクリップボードにコピーするコマンド</h1>

<p>文字列の内容を Repo → Settings → Secrets and variables → Actions → 新しい Secret を追加：<code class="language-plaintext highlighter-rouge">APP_STORE_CONNECT_API_KEY_BASE64</code> に貼り付けてください。</p>

<p><img src="/assets/4b001d2e8440/1*QxRuxEPEfWbJ383hhnxGkA.webp" alt="" loading="lazy" decoding="async" width="1159" height="549" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTU5IiBoZWlnaHQ9IjU0OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*QxRuxEPEfWbJ383hhnxGkA.png" /></p>

<p><code class="language-plaintext highlighter-rouge">Read and Write Apple Store Connect API Key to Temp</code> ステップ完了後、以降のステップでは env <code class="language-plaintext highlighter-rouge">APP_STORE_CONNECT_API_KEY_PATH</code> を渡すだけで良いです：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy</span>
  <span class="na">env</span><span class="pi">:</span>
    <span class="na">APP_STORE_CONNECT_API_KEY_PATH</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">runner.temp</span><span class="nv"> </span><span class="s">}}/${{</span><span class="nv"> </span><span class="s">env.APP_STORE_CONNECT_API_KEY_FILE_NAME</span><span class="nv"> </span><span class="s">}}"</span>
  <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
    <span class="s">....</span>
</code></pre></div></div>

<p>Fastlane を使えば自動で取得できます。</p>

<h4 id="技術拡張--reuse-action-workflow-でビルドとデプロイの処理を分割する">技術拡張 — Reuse Action Workflow でビルドとデプロイの処理を分割する</h4>

<p>このケースでは、Fastlane の <code class="language-plaintext highlighter-rouge">beta</code> レーンを使ってビルドとデプロイの2つの処理を直接実行します。</p>

<p>実際のケースでは、同じビルド成果物を異なるプラットフォーム（Firebase、Testflightなど）にそれぞれデプロイする必要があります。そのため、ビルドは1つのAction、デプロイは別のActionに分けるのが望ましいです。そうしないとビルドが2回実行されてしまいますし、CI/CDの責任分担にも合致します。</p>

<blockquote>
  <p><strong><em>以下はサンプル紹介です：</em></strong></p>
</blockquote>

<p><strong>CI-Build.yml:</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Build</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="na">push</span><span class="pi">:</span>
    <span class="na">branches</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">main</span>
  <span class="na">workflow_call</span><span class="pi">:</span>
     <span class="na">inputs</span><span class="pi">:</span>
        <span class="na">RELEASE_NOTE</span><span class="pi">:</span>
          <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">デプロイのリリースノート。'</span>
          <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
          <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">build</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">macos-latest</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">コードをチェックアウト</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">依存関係をインストール</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">make steup</span>
          <span class="s">make instal</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">プロジェクトをビルド</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">bundle exec fastlane build</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">ビルド成果物をアップロード</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/upload-artifact@v4</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">name</span><span class="pi">:</span> <span class="s">build-artifact</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">./fastlane/build/</span>
</code></pre></div></div>

<p><strong>CD-Deploy-Firebase.yml:</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Deploy Firebase</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># Build Actionが完了したときに自動で実行</span>
  <span class="na">workflow_run</span><span class="pi">:</span>
    <span class="na">workflows</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">Build"</span><span class="pi">]</span>
    <span class="na">types</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">completed</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">deploy</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="c1"># 完了かつ成功した場合のみデプロイを実行</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">${{ github.event.workflow_run.conclusion == 'success' }}</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout Code</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install Dependencies</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">make steup</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Download Build Artifact</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/download-artifact@v4</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">name</span><span class="pi">:</span> <span class="s">build-artifact</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">./fastlane/build/</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy to Production</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">bundle exec fastlane deploy-firebase</span>
</code></pre></div></div>

<p><strong>CD-Deploy-Testflight.yml:</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Deploy Testflight</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># Build Action 完了時に自動で実行をトリガー</span>
  <span class="na">workflow_run</span><span class="pi">:</span>
    <span class="na">workflows</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">Build"</span><span class="pi">]</span>
    <span class="na">types</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">completed</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">deploy</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="c1"># 完了かつ成功した場合のみデプロイを実行</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">${{ github.event.workflow_run.conclusion == 'success' }}</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout Code</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install Dependencies</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">make steup</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Download Build Artifact</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/download-artifact@v4</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">name</span><span class="pi">:</span> <span class="s">build-artifact</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">./fastlane/build/</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy to Production</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">bundle exec fastlane deploy-testflight</span>
</code></pre></div></div>

<p><strong>また、<a href="https://docs.github.com/en/actions/how-tos/sharing-automations/reusing-workflows" target="_blank">Reusing Workflow</a> を使うこともできます：</strong></p>

<p><strong>CD-Deploy-Firebase.yml:</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Deploy Firebase</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># 任意のトリガー条件、ここでは手動フォームトリガーの例</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>
    <span class="na">inputs</span><span class="pi">:</span>
      <span class="na">RELEASE_NOTE</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">デプロイのリリースノート。'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">build</span><span class="pi">:</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="s">Build</span>
    <span class="na">uses</span><span class="pi">:</span> <span class="s">./.github/workflows/CD-Build.yml</span>
    <span class="na">secrets</span><span class="pi">:</span> <span class="s">inherit</span>
    <span class="na">with</span><span class="pi">:</span>
      <span class="na">RELEASE_NOTE</span><span class="pi">:</span> <span class="s">${{ inputs.RELEASE_NOTE }}</span>

  <span class="na">deploy</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="c1"># ジョブはデフォルトで並行実行、needsでbuild完了まで待機するよう制限</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">build</span><span class="pi">]</span>
    <span class="c1"># 成功時のみデプロイ実行</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">${{ always() &amp;&amp; needs.deploy.result == 'success' }}</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout Code</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v4</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install Dependencies</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">make steup</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Download Build Artifact</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/download-artifact@v4</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">name</span><span class="pi">:</span> <span class="s">build-artifact</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s">./fastlane/build/</span>

      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy to Production</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">bundle exec fastlane deploy-firebase</span>
</code></pre></div></div>

<h4 id="github-actions--artifact">GitHub Actions — Artifact</h4>

<p>キャッシュと同様に、現在 <strong>Self-hosted Runner の Artifact 機能も GitHub Cloud を経由するため</strong> 使用量制限を受けます ( <a href="https://docs.github.com/en/billing/managing-billing-for-your-products/about-billing-for-github-actions#included-storage-and-minutes" target="_blank">無料アカウントは500MBから</a> )。</p>

<blockquote>
  <p><em>Self-hosted Runnerで同様の効果を得るには、共有ホストディレクトリを自分で作成するか、他のツールを代替として使用してください。</em></p>
</blockquote>

<p>したがって、現在 Artifact は実際にはスナップショットテストのエラー結果やテストレポートなどの小さなデータを保存するためにのみ使用しています。</p>

<h3 id="ci-nightly-build-スナップショット実行単体テストビルドcd-firebase-app-distribution-へのデプロイ">CI— Nightly Build スナップショット実行＋単体テスト＋ビルド＋CD Firebase App Distribution へのデプロイ</h3>

<h4 id="フロー-2">フロー</h4>

<p>毎日午前3時に main（develop または master）ブランチに対して全てのテスト（ユニット＋スナップショットテスト）を自動実行し、失敗した場合は Slack ワークスペースに失敗通知を送信します。成功した場合はビルドして Firebase App Distribution にデプロイし、ビルドの成功・失敗いずれも Slack に通知します。</p>

<h4 id="ci-nightly-build-and-deployyml">CI-Nightly-Build-And-Deploy.yml</h4>

<p>Repo → Actions → New workflow → ワークフローを自分で設定する。</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ワークフロー(Action) 名称</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">CI-Nightly Build And Deploy</span>

<span class="c1"># Actions ログのタイトル名</span>
<span class="na">run-name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">[CI-Nightly</span><span class="nv"> </span><span class="s">Build</span><span class="nv"> </span><span class="s">And</span><span class="nv"> </span><span class="s">Deploy]</span><span class="nv"> </span><span class="s">${{</span><span class="nv"> </span><span class="s">github.ref</span><span class="nv"> </span><span class="s">}}"</span>

<span class="c1"># トリガーイベント</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># スケジュール定期自動実行</span>
  <span class="c1"># https://crontab.guru/</span>
  <span class="c1"># UTC 時間</span>
  <span class="na">schedule</span><span class="pi">:</span>
    <span class="c1"># UTC の 19:00 = 毎日 UTC+8 の 03:00</span>
    <span class="pi">-</span> <span class="na">cron</span><span class="pi">:</span> <span class="s1">'</span><span class="s">0</span><span class="nv"> </span><span class="s">19</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">*'</span>
  <span class="c1"># 手動トリガー</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>

<span class="c1"># Job 作業項目</span>
<span class="c1"># Job は並行実行される</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="c1"># テスト作業</span>
  <span class="na">testing</span><span class="pi">:</span>
    <span class="c1"># Reuse Workflow (workflow_call)</span>
    <span class="na">uses</span><span class="pi">:</span> <span class="s">./.github/workflows/CI-Testing.yml</span>
    <span class="c1"># すべての Secrets を CD-Testing.yml に渡す</span>
    <span class="na">secrets</span><span class="pi">:</span> <span class="s">inherit</span>
    <span class="na">with</span><span class="pi">:</span>
      <span class="c1"># 全テストを実行</span>
      <span class="na">TEST_LANE</span><span class="pi">:</span> <span class="s2">"</span><span class="s">run_all_tests"</span>
      <span class="c1"># 対象ブランチ：main, develop or master...etc</span>
      <span class="na">BRANCH</span><span class="pi">:</span> <span class="s2">"</span><span class="s">main"</span>

  <span class="na">deploy-env</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">outputs</span><span class="pi">:</span>
      <span class="na">DATE_STRING</span><span class="pi">:</span> <span class="s">${{ steps.get_date.outputs.DATE_STRING }}</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">日付文字列を取得</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">get_date</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">VERSION_DATE=$(date -u '+%Y%m%d')</span>
          <span class="s">echo "${VERSION_DATE}"</span>
          <span class="s">echo "DATE_STRING=${VERSION_DATE}" &gt;&gt; $GITHUB_ENV</span>
          <span class="s">echo "DATE_STRING=${VERSION_DATE}" &gt;&gt; $GITHUB_OUTPUT</span>
    
  <span class="na">deploy</span><span class="pi">:</span>
    <span class="c1"># Job はデフォルトで並行実行、needs で testing と deploy-env の完了を待つ</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">testing</span><span class="pi">,</span> <span class="nv">deploy-env</span><span class="pi">]</span>
    <span class="c1"># テスト成功時のみ実行</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">${{ needs.testing.result == 'success' }}</span>
    <span class="c1"># Reuse Workflow (workflow_call)</span>
    <span class="na">uses</span><span class="pi">:</span> <span class="s">./.github/workflows/CD-Deploy.yml</span>
    <span class="c1"># すべての Secrets を CD-Deploy.yml に渡す</span>
    <span class="na">secrets</span><span class="pi">:</span> <span class="s">inherit</span>
    <span class="na">with</span><span class="pi">:</span>
      <span class="na">VERSION_NUMBER</span><span class="pi">:</span> <span class="s">NightlyBuild-${{ needs.deploy-env.outputs.DATE_STRING }}</span>
      <span class="na">RELEASE_NOTE</span><span class="pi">:</span> <span class="s">NightlyBuild-${{ needs.deploy-env.outputs.DATE_STRING }}</span>
      <span class="c1"># 対象ブランチ：main, develop or master...etc</span>
      <span class="na">BRANCH</span><span class="pi">:</span> <span class="s2">"</span><span class="s">main"</span>

<span class="c1"># ----- Slack 通知 -----</span>
  <span class="na">testing-failed-slack-notify</span><span class="pi">:</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">testing</span><span class="pi">]</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">${{ needs.testing.result == 'failure' }}</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Slack チャンネルにテキストを投稿</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">slackapi/slack-github-action@v2.1.0</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">method</span><span class="pi">:</span> <span class="s">chat.postMessage</span>
          <span class="na">token</span><span class="pi">:</span> <span class="s">${{ secrets.SLACK_BOT_TOKEN }}</span>
          <span class="na">payload</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">channel</span><span class="err">:</span> <span class="s">${{ vars.SLACK_TEAM_CHANNEL_ID }}</span>
            <span class="s">text</span><span class="err">:</span> <span class="s2">"</span><span class="s">:x:</span><span class="nv"> </span><span class="s">Nightly</span><span class="nv"> </span><span class="s">Build</span><span class="nv"> </span><span class="s">-</span><span class="nv"> </span><span class="s">テスト失敗</span><span class="se">\n</span><span class="s">Workflow:</span><span class="nv"> </span><span class="s">&lt;${{</span><span class="nv"> </span><span class="s">github.server_url</span><span class="nv"> </span><span class="s">}}/${{</span><span class="nv"> </span><span class="s">github.repository</span><span class="nv"> </span><span class="s">}}/actions/runs/${{</span><span class="nv"> </span><span class="s">github.run_id</span><span class="nv"> </span><span class="s">}}</span><span class="se">\\</span><span class="s">|実行を表示&gt;"</span>

  <span class="na">deploy-failed-slack-notify</span><span class="pi">:</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">deploy</span><span class="pi">]</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">${{ needs.deploy.result == 'failure' }}</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Slack チャンネルにテキストを投稿</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">slackapi/slack-github-action@v2.1.0</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">method</span><span class="pi">:</span> <span class="s">chat.postMessage</span>
          <span class="na">token</span><span class="pi">:</span> <span class="s">${{ secrets.SLACK_BOT_TOKEN }}</span>
          <span class="na">payload</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">channel</span><span class="err">:</span> <span class="s">${{ vars.SLACK_TEAM_CHANNEL_ID }}</span>
            <span class="s">text</span><span class="err">:</span> <span class="s2">"</span><span class="s">:x:</span><span class="nv"> </span><span class="s">Nightly</span><span class="nv"> </span><span class="s">Build</span><span class="nv"> </span><span class="s">Deploy</span><span class="nv"> </span><span class="s">失敗</span><span class="se">\n</span><span class="s">Workflow:</span><span class="nv"> </span><span class="s">&lt;${{</span><span class="nv"> </span><span class="s">github.server_url</span><span class="nv"> </span><span class="s">}}/${{</span><span class="nv"> </span><span class="s">github.repository</span><span class="nv"> </span><span class="s">}}/actions/runs/${{</span><span class="nv"> </span><span class="s">github.run_id</span><span class="nv"> </span><span class="s">}}</span><span class="se">\\</span><span class="s">|実行を表示&gt;"</span>

  <span class="na">deploy-success-slack-notify</span><span class="pi">:</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">deploy</span><span class="pi">]</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">${{ needs.deploy.result == 'success' }}</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Slack チャンネルにテキストを投稿</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">slackapi/slack-github-action@v2.1.0</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">method</span><span class="pi">:</span> <span class="s">chat.postMessage</span>
          <span class="na">token</span><span class="pi">:</span> <span class="s">${{ secrets.SLACK_BOT_TOKEN }}</span>
          <span class="na">payload</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">channel</span><span class="err">:</span> <span class="s">${{ vars.SLACK_TEAM_CHANNEL_ID }}</span>
            <span class="s">text</span><span class="err">:</span> <span class="s2">"</span><span class="s">:white_check_mark:</span><span class="nv"> </span><span class="s">Nightly</span><span class="nv"> </span><span class="s">Build</span><span class="nv"> </span><span class="s">Deploy</span><span class="nv"> </span><span class="s">成功</span><span class="se">\n</span><span class="s">Workflow:</span><span class="nv"> </span><span class="s">&lt;${{</span><span class="nv"> </span><span class="s">github.server_url</span><span class="nv"> </span><span class="s">}}/${{</span><span class="nv"> </span><span class="s">github.repository</span><span class="nv"> </span><span class="s">}}/actions/runs/${{</span><span class="nv"> </span><span class="s">github.run_id</span><span class="nv"> </span><span class="s">}}</span><span class="se">\\</span><span class="s">|実行を表示&gt;"</span>
</code></pre></div></div>

<p><strong>Commit ファイルをリポジトリのメインブランチにプッシュし、手動でテストとビルドを実行して結果を確認します：</strong></p>

<p><img src="/assets/4b001d2e8440/1*l71fL8oLoeAv-JX_FgkqzQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="564" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjU2NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*l71fL8oLoeAv-JX_FgkqzQ.png" /></p>

<blockquote>
  <p><em>今後は毎日自動でトリガーされます。</em></p>
</blockquote>

<p><img src="/assets/4b001d2e8440/1*u6A77KwkXS2SY5-DPPPR9A.webp" alt="Demo" loading="lazy" decoding="async" width="1200" height="802" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*u6A77KwkXS2SY5-DPPPR9A.png" /></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/actions/runs/16119750747" target="_blank">Demo</a></p>

<p><img src="/assets/4b001d2e8440/1*6DQL_v4eahSqSuVJZRPrEA.webp" alt="" loading="lazy" decoding="async" width="310" height="92" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMTAiIGhlaWdodD0iOTIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/4b001d2e8440/1*6DQL_v4eahSqSuVJZRPrEA.png" /></p>

<p>テストタスク、ビルド＆デプロイタスク、通知タスクがすべて完了したら、結果を確認します。</p>

<p><img src="/assets/4b001d2e8440/1*4UVgyCQljqZQgzxHpXPB4g.webp" alt="" loading="lazy" decoding="async" width="903" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDMiIGhlaWdodD0iOTAwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*4UVgyCQljqZQgzxHpXPB4g.png" /></p>

<p><img src="/assets/4b001d2e8440/1*t9PrQfcTANyvG7gfXXC-bw.webp" alt="" loading="lazy" decoding="async" width="554" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*t9PrQfcTANyvG7gfXXC-bw.jpeg" /></p>

<p>私たちは直接スマホに Nightly Build バージョンをインストールして、先行体験テストを行うことができます。</p>

<h4 id="技術的詳細情報">技術的詳細情報</h4>

<p>この Action は前に設計した CI-Testing と CD-Deploy をそのまま再利用し、Nightly Build に組み合わせています。非常に柔軟で使いやすいです！</p>

<p><strong>完全なコード： <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/actions/workflows/CI-Nightly-Build-And-Deploy.yml" target="_blank">CI-Nightly-Build-And-Deploy.yml</a></strong></p>

<h3 id="self-hosted-runner-注意事項">Self-hosted Runner 注意事項</h3>

<p>本文は Public Repo なので直接 GitHub Hosted の macOS Runner を使用していますが、実際の業務では私たちの Repo は必ず Private です。直接 GitHub Hosted Runner を使うのは非常に高価で割に合いません（だいたい1ヶ月分で会社に Mac Mini を買って設置し、使い放題で快適に動かせます）。各マシンは性能に応じて複数の Runner を同時に起動し、並行してタスクを処理できます。</p>

<blockquote>
  <p><strong><em>詳細は<a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/">前回の記事</a>の「<a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/">Self-hosted Runnerの構築と切り替え</a>」部分をご参照ください</em></strong> <em>。ローカルPCにXCodeと基本環境をインストール後、Runnerを登録・有効化し、Action WorkflowのYAMLで<code class="language-plaintext highlighter-rouge">runs-on</code>を<code class="language-plaintext highlighter-rouge">[self-hosted]</code>に変更するだけです。</em></p>
</blockquote>

<p>複数の Runner が同じコンピュータ上で動作する問題は、上記の Actions でほとんど解決しています。例えば、すべての依存共有ディレクトリをローカルディレクトリに変更することなどです。さらに、テストで直面する問題として、シミュレーターの競合問題があります。「<strong>同じマシン上で2つの Runner が同じシミュレーターを指定して同時に2つのテストジョブを実行すると、互いに干渉しテストが失敗する。</strong>」</p>

<p>解決策も簡単で、各 Runner に対してそれぞれ1台のシミュレーターを設定するだけです。</p>

<h4 id="複数のrunnerを同じマシンで使う際のシミュレーター設定">複数のRunnerを同じマシンで使う際のシミュレーター設定</h4>

<p>同じコンピュータ上に <strong>2つの Runner</strong> が並行してジョブを受け取る場合：</p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">ZhgChgLideMacBook-Pro-Runner-A</code></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">ZhgChgLideMacBook-Pro-Runner-B</code></p>
  </li>
</ul>

<p><img src="/assets/4b001d2e8440/1*3ptg9Tl5fBbEIYB4kgh0kw.webp" alt="" loading="lazy" decoding="async" width="819" height="333" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MTkiIGhlaWdodD0iMzMzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*3ptg9Tl5fBbEIYB4kgh0kw.png" /></p>

<p>XCode シミュレーターの設定では、2つのシミュレーターを追加する必要があります：</p>

<p><img src="/assets/4b001d2e8440/1*k9bR2C12Wk11HAKKiYJ2zg.webp" alt="" loading="lazy" decoding="async" width="1037" height="695" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDM3IiBoZWlnaHQ9IjY5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*k9bR2C12Wk11HAKKiYJ2zg.png" /></p>

<p><img src="/assets/4b001d2e8440/1*iigArewZEW0063Q6xwZn7g.webp" alt="" loading="lazy" decoding="async" width="322" height="281" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMjIiIGhlaWdodD0iMjgxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*iigArewZEW0063Q6xwZn7g.png" /></p>

<ul>
  <li>モデル、iOS バージョンおよびテスト環境</li>
</ul>

<p><strong>CI-Testing.yml のテストステップを以下のように変更：</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># FastlaneのUnitテストLaneを実行</span>
      - name: Run Tests
        <span class="nb">id</span>: testing
        <span class="c"># 作業ディレクトリを指定、これにより後続コマンドで特にcd ./Product/する必要がない</span>
        working-directory: ./Product/
        <span class="nb">env</span>:
          <span class="c"># ...</span>
          <span class="c"># Repo -&gt; Settings -&gt; Actions secrets and variables -&gt; variables</span>
          <span class="c"># シミュレーターのiOSバージョン</span>
          SIMULATOR_IOS_VERSION: <span class="k">${</span><span class="p">{ vars.SIMULATOR_IOS_VERSION </span><span class="k">}</span><span class="o">}</span>

          <span class="c"># 現在のRunner名</span>
          RUNNER_NAME: <span class="k">${</span><span class="p">{ runner.name </span><span class="k">}</span><span class="o">}</span>
          
          <span class="c"># ...</span>
        run: <span class="se">\\</span>|

          <span class="c"># ...</span>
          bundle <span class="nb">exec </span>fastlane <span class="k">${</span><span class="nv">TEST_LANE</span><span class="k">}</span> device:<span class="s2">"</span><span class="k">${</span><span class="nv">RUNNER_NAME</span><span class="k">}</span><span class="s2"> (</span><span class="k">${</span><span class="nv">SIMULATOR_IOS_VERSION</span><span class="k">}</span><span class="s2">)"</span> <span class="se">\\</span>| <span class="nb">tee</span> <span class="s2">"</span><span class="nv">$RUNNER_TEMP</span><span class="s2">/testing_output.txt"</span>
          <span class="c"># ...</span>
</code></pre></div></div>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">device</code> <strong>を</strong> <code class="language-plaintext highlighter-rouge">${RUNNER_NAME} (${SIMULATOR_IOS_VERSION})</code> <strong>に変更</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">SIMULATOR_IOS_VERSION</code> は引き続きリポジトリの変数を参照します。</p>
  </li>
</ul>

<p><strong>組み合わせ結果は（18.4を例に）：</strong></p>

<ul>
  <li>
    <p>Runner: <code class="language-plaintext highlighter-rouge">ZhgChgLideMacBook-Pro-Runner-A</code><br />
シミュレーター: <strong>ZhgChgLideMacBook-Pro-Runner-A(18.4)</strong></p>
  </li>
  <li>
    <p>Runner: <code class="language-plaintext highlighter-rouge">ZhgChgLideMacBook-Pro-Runner-B</code><br />
シミュレーター: <strong>ZhgChgLideMacBook-Pro-Runner-B(18.4)</strong></p>
  </li>
</ul>

<p>こうすると、2つのランナーが同時にテストを実行している場合、それぞれが別々のシミュレーターを起動して独立して動作します。</p>

<h4 id="完全なプロジェクトリポジトリ">完全なプロジェクトリポジトリ</h4>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo" target="_blank"><img src="https://opengraph.githubassets.com/eb233d74ad1bc6b0eceb9494487579557fb7f17066a3981d20b52fde2c00ef45/ZhgChgLi/github-actions-ci-cd-demo" alt="" /></a></p>

<h3 id="ssh-agent-設定の補足--fastlane-match-またはプライベート-cocoapods-リポジトリ用">SSH Agent 設定の補足 — Fastlane Match またはプライベート CocoaPods リポジトリ用</h3>

<p>Fastlane Match や Private CocoaPods Repo を使用する場合、別の Private Repo 内にあるため、現在の Repo/Action 環境では直接 git clone できません。ssh agent を設定して環境を整え、Action 実行時に操作権限を持たせる必要があります。</p>

<h4 id="step-1-sshキーを生成する">Step 1. SSHキーを生成する</h4>

<p><img src="/assets/4b001d2e8440/1*kPWl9hombBgQ15i-n2sY2A.webp" alt="" loading="lazy" decoding="async" width="682" height="483" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2ODIiIGhlaWdodD0iNDgzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*kPWl9hombBgQ15i-n2sY2A.png" /></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen <span class="nt">-t</span> ed25519 <span class="nt">-C</span> <span class="s2">"zhgchgli@gmail.com"</span>
</code></pre></div></div>
<h1 id="ssh-キーを生成するコマンド">SSH キーを生成するコマンド</h1>

<p><code class="language-plaintext highlighter-rouge">Enter file in which to save the key (/Users/zhgchgli/.ssh/id_ed25519):</code> /Users/zhgchgli/Downloads/zhgchgli</p>

<ul>
  <li>ダウンロードパスに入力すると、内容のコピーが簡単になります。</li>
</ul>

<p><code class="language-plaintext highlighter-rouge">“/Users/zhgchgli/Downloads/zhgchgli” のパスフレーズを入力してください（パスフレーズなしの場合は空のまま）：</code></p>

<ul>
  <li>
    <p><strong>空欄にしてください：</strong> CI/CDで使用するため、CLIの対話式入力でパスフレーズを入力できません。<strong>そのため空欄にしてください</strong></p>
  </li>
  <li>
    <p>生成完了 (.pub/private_key)</p>
  </li>
</ul>

<p><img src="/assets/4b001d2e8440/1*aF5P6EK9Hfv-CI3MRZ8MCA.webp" alt="" loading="lazy" decoding="async" width="220" height="51" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMjAiIGhlaWdodD0iNTEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/4b001d2e8440/1*aF5P6EK9Hfv-CI3MRZ8MCA.png" /></p>

<h4 id="step-2-private-repo-に-deploy-key-を設定する">Step 2. Private Repo に Deploy Key を設定する</h4>

<p><img src="/assets/4b001d2e8440/1*3K6JvCHa23QfvWoNq2xdBQ.webp" alt="github-actions-ci-cd-demo-certificates Repo" loading="lazy" decoding="async" width="1172" height="781" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTcyIiBoZWlnaHQ9Ijc4MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*3K6JvCHa23QfvWoNq2xdBQ.jpeg" /></p>

<p>github-actions-ci-cd-demo-certificates リポジトリ</p>

<p>Settings → Security → Deploy keys → Add deploy key。</p>

<ul>
  <li>
    <p>Title: キー名を入力してください</p>
  </li>
  <li>
    <p>Key: <code class="language-plaintext highlighter-rouge">.pub キーの内容を貼り付ける</code></p>
  </li>
</ul>

<p>完了。</p>

<p><img src="/assets/4b001d2e8440/1*Xo_g-AchEk0j4SGXOmBuxg.webp" alt="" loading="lazy" decoding="async" width="1168" height="814" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTY4IiBoZWlnaHQ9IjgxNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*Xo_g-AchEk0j4SGXOmBuxg.jpeg" /></p>

<h4 id="step-3-action-のリポジトリに-ssh-プライベートキーを-secrets-に設定する">Step 3. Action のリポジトリに SSH プライベートキーを Secrets に設定する</h4>

<p><img src="/assets/4b001d2e8440/1*Jm92pQHMOImQzZtmmvd1ng.webp" alt="github-actions-ci-cd-demo リポジトリ" loading="lazy" decoding="async" width="1174" height="899" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTc0IiBoZWlnaHQ9Ijg5OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*Jm92pQHMOImQzZtmmvd1ng.jpeg" /></p>

<p>github-actions-ci-cd-demo リポジトリ</p>

<p>Settings → Secrets and variables → Actions → New repository secret。</p>

<ul>
  <li>
    <p>Name: キー変数名 <code class="language-plaintext highlighter-rouge">SSH_PRIVATE_KEY</code> を入力してください</p>
  </li>
  <li>
    <p>Secret: <code class="language-plaintext highlighter-rouge">private_key の内容を貼り付け</code></p>
  </li>
</ul>

<p>完了。</p>

<h4 id="step-4-ssh-agent-設定完了らgit-clone-private-repo-の権限を確認しましょう">Step 4. SSH Agent 設定完了ら、Git Clone Private Repo の権限を確認しましょう</h4>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/actions/workflows/Demo-Git-Clone-Private-Repo.yml" target="_blank"><strong>Demo-Git-Clone-Private-Repo.yml</strong></a> <strong>：</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Demo Git Clone Private Repo</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">clone-private-repo</span><span class="pi">:</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">Git Clone Private Repo</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">30</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="c1"># 🔐 SSHエージェントを起動して秘密鍵を追加</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup SSH Agent</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">webfactory/ssh-agent@v0.9.0</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">ssh-private-key</span><span class="pi">:</span> <span class="s">${{ secrets.SSH_PRIVATE_KEY }}</span>

      <span class="c1"># 🛡️ host verificationエラーを防ぐためにgithub.comをknown_hostsに追加</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Add GitHub to known_hosts</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">mkdir -p ~/.ssh</span>
          <span class="s">ssh-keyscan github.com &gt;&gt; ~/.ssh/known_hosts</span>
      <span class="c1"># 📦 SSHでプライベートリポジトリをクローンし検証</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Clone and Verify Private Repo</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">git clone git@github.com:ZhgChgLi/github-actions-ci-cd-demo-certificates.git ./fakeMatch/</span>
          <span class="s">if [ -d "./fakeMatch/.git" ]; then</span>
            <span class="s">echo "✅ ./fakeMatch/にリポジトリを正常にクローンしました"</span>
            <span class="s">cd ./fakeMatch</span>
            <span class="s">echo "📌 現在のコミット</span><span class="err">:</span> <span class="s">$(git rev-parse --short HEAD)"</span>
          <span class="s">else</span>
            <span class="s">echo "❌ クローンに失敗しました。SSHエージェントの設定が正しくない可能性があります。"</span>
            <span class="s">exit </span><span class="m">1</span>
          <span class="s">fi</span>
</code></pre></div></div>

<p>上記の Action を使って設定が正しく行われているか確認できます。</p>

<p><img src="/assets/4b001d2e8440/1*YLbr7l0FBSOYx_fQT-tiCA.webp" alt="" loading="lazy" decoding="async" width="1400" height="805" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjgwNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4b001d2e8440/1*YLbr7l0FBSOYx_fQT-tiCA.png" /></p>

<p>成功しました。これで <code class="language-plaintext highlighter-rouge">fastlane match</code> や <code class="language-plaintext highlighter-rouge">pod install</code> のプライベートポッドも正しく実行できるはずです。</p>

<h3 id="まとめ">まとめ</h3>

<p>この記事は GitHub Actions を使った完全な iOS CI/CD フローの開発を詳細に記録しています。次回はユーザー側（エンジニア/PM/デザイナー）の体験を最適化し、<strong>Slack 通知の充実と Google Apps Script Web App を連携した GitHub Actions を活用した無料で使いやすいチーム横断のパッケージングプラットフォームツールの構築</strong>について解説します。</p>

<h3 id="シリーズ記事">シリーズ記事：</h3>

<ul>
  <li>
    <p><a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/"><strong>CI/CD 実践ガイド（1）：CI/CD とは？安定かつ効率的な開発チームを作るための使い方とツール選定</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/"><strong>CI/CD 実践ガイド（二）：GitHub Actions とセルフホストランナーの使い方と構築完全ガイド</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/"><strong>CI/CD 実践ガイド（三）：GitHub Actions を使ったアプリプロジェクトの CI/CD ワークフロー実装</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/"><strong>CI/CD 実践ガイド（4）：Google Apps Script Web App を活用し、GitHub Actions と連携した無料で使いやすいパッケージングツールプラットフォームの構築</strong></a></p>
  </li>
</ul>

<h4 id="-buy-me-a-beer-on-paypal"><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank">🍺 Buy me a beer on PayPal</a></h4>

<blockquote>
  <p><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank"><strong><em>本シリーズの記事は多くの時間と労力をかけて執筆しています。内容があなたやチームの作業効率や製品品質向上に役立つ場合は、ぜひコーヒーをご馳走してください。ご支援ありがとうございます！</em></strong></a></p>
</blockquote>

<p><img src="/assets/4b001d2e8440/1*QJj54G9gOjtQS-rbHVT1SQ.webp" alt="Buy me a coffee" loading="lazy" decoding="async" width="700" height="700" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiIGhlaWdodD0iNzAwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4b001d2e8440/1*QJj54G9gOjtQS-rbHVT1SQ.png" /></p>

<p><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank">コーヒーをおごる</a></p>

<p>*<a href="https://medium.com/zrealm-ios-dev/ci-cd-%E5%AF%A6%E6%88%B0%E6%8C%87%E5%8D%97-%E4%B8%89-%E4%BD%BF%E7%94%A8-github-actions-%E5%AF%A6%E4%BD%9C-app-ios-ci-%E8%88%87-cd-%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B-4b001d2e8440" target="_blank">Post</a> は Medium から <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a> によって変換されました。</p>]]></content>
  </entry><entry>
    <title type="html">GitHub Actions｜Self-hosted Runner：CI/CD 実践ガイドで自動化効率最大化</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89%E3%81%A7%E8%87%AA%E5%8B%95%E5%8C%96%E5%8A%B9%E7%8E%87%E6%9C%80%E5%A4%A7%E5%8C%96-404bd5c70040/" rel="alternate" type="text/html" title="GitHub Actions｜Self-hosted Runner：CI/CD 実践ガイドで自動化効率最大化" />
    <published>2025-07-02T20:22:32+08:00</published>
    <updated>2025-07-12T22:49:01+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-dev/404bd5c70040</id><summary type="html">GitHub ActionsとSelf-hosted Runnerの基本から応用までを詳解。設定の悩みを解消し、CI/CDパイプラインの自動化をスムーズに実現する具体的手法を紹介。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm Dev." /><category term="iosアプリ開発" /><category term="ci-cd" /><category term="github-actions" /><category term="github" /><category term="セルフホスティング" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/404bd5c70040/1*_vGYh_XSI3ZDbdeT8xCihA.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89%E3%81%A7%E8%87%AA%E5%8B%95%E5%8C%96%E5%8A%B9%E7%8E%87%E6%9C%80%E5%A4%A7%E5%8C%96-404bd5c70040/"><![CDATA[<h3 id="cicd-実践ガイド二github-actions-と-self-hosted-runner-の使用と構築大全">CI/CD 実践ガイド（二）：GitHub Actions と Self-hosted Runner の使用と構築大全</h3>

<p>GitHub Actions/Self-hosted Runner の仕組みと使い方をゼロから解説します。</p>

<p><img src="/assets/404bd5c70040/1*_vGYh_XSI3ZDbdeT8xCihA.webp" alt="Photo by Dan Taylor" loading="lazy" decoding="async" width="1400" height="933" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjkzMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*_vGYh_XSI3ZDbdeT8xCihA.jpeg" /></p>

<p>Photo by <a href="https://unsplash.com/@theoneandonlydantaylor?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash" target="_blank">Dan Taylor</a></p>

<h4 id="はじめに">はじめに</h4>

<p>前回の「<a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/"><strong>CI/CD 実践ガイド（一）：CI/CD とは？CI/CD を使って安定かつ効率的な開発チームを作るには？ツールの選び方は？</strong></a>」では、CI/CD とは何か、得られる効果やツールの選び方について紹介しました。<strong>今回は GitHub Actions と Self-hosted Runner の構成と使い方に重点を置き</strong>、いくつかの面白い自動化ワークフローを一緒に作りながら、丁寧に解説していきます。</p>

<h3 id="github-actions-アーキテクチャフローチャート">GitHub Actions アーキテクチャフローチャート</h3>

<p>開始する前に、まず GitHub Actions の動作構造、フローの関係、および役割を確認しましょう。</p>

<p><img src="/assets/404bd5c70040/1*iacfyTX_b3YTSzMcn2ldjw.webp" alt="" loading="lazy" decoding="async" width="1400" height="937" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjkzNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*iacfyTX_b3YTSzMcn2ldjw.png" /></p>

<h4 id="github-リポジトリ"><strong>GitHub リポジトリ</strong></h4>

<ul>
  <li>GitHub Actions の世界では、すべての Actions（Workflow YAML ファイル）は必ずある Git リポジトリ内の <code class="language-plaintext highlighter-rouge">REPO/.github/workflows/</code> に保存されます。</li>
</ul>

<h4 id="github-リポジトリ--actions-secrets">GitHub リポジトリ — Actions Secrets</h4>

<p>Repo → 設定 → Secrets and variables → Actions → Secrets。</p>

<ul>
  <li>
    <p>Actions のステップで使用する Secret Key や Token を保存<br />
例：Slack Bot Token、Apple Store Connect API の .p8 キー</p>
  </li>
  <li>
    <p><strong>Secrets の内容は Action ログに表示されず、自動的に **</strong> でマスクされます**</p>
  </li>
  <li>
    <p>Secrets の内容は閲覧や編集ができず、上書きのみ可能です。</p>
  </li>
  <li>
    <p>Secrets <strong>は現在テキストのみ対応しており、ファイルのアップロードはできません</strong><br />
<strong>-</strong> バイナリデータの場合は、<a href="https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/using-secrets-in-github-actions#storing-base64-binary-blobs-as-secrets" target="_blank">公式手順のBase64エンコードを使って保存する方法</a> を参照してください。</p>
  </li>
  <li>
    <p>iOS 開発証明書の保存方法は公式ガイドを参照してください： <a href="https://docs.github.com/en/actions/how-tos/use-cases-and-examples/deploying/installing-an-apple-certificate-on-macos-runners-for-xcode-development" target="_blank">Installing an Apple certificate on macOS runners for Xcode development</a></p>
  </li>
  <li>
    <p>組織レベルの Secrets を保存でき、リポジトリ間で共有可能</p>
  </li>
</ul>

<h4 id="github-repo--actions-変数">GitHub Repo — Actions 変数</h4>

<p>Repo → 設定 → Secrets and variables → Actions → Variables。</p>

<ul>
  <li>
    <p>Actions のステップでよく使う変数を格納<br />
例：シミュレーターの iOS バージョン、作業ディレクトリ</p>
  </li>
  <li>
    <p>Variables の内容は閲覧および編集可能です</p>
  </li>
  <li>
    <p>Variables の内容は Action Log に出力できます</p>
  </li>
  <li>
    <p>Variables はプレーンテキストのみをサポートしており、JSON文字列を保存して自分で解析して使用することもできます。</p>
  </li>
  <li>
    <p>組織レベルの Variables を保存でき、リポジトリ間で共有可能です。</p>
  </li>
</ul>

<h4 id="github-actions--トリガー">GitHub Actions — トリガー</h4>

<ul>
  <li>
    <p><strong>Github Action における最も重要な出発点 — トリガーイベント（条件）</strong></p>
  </li>
  <li>
    <p>トリガーイベントに一致する GitHub Actions のみが実行されます</p>
  </li>
  <li>
    <p>完全なイベント一覧は<a href="https://docs.github.com/en/actions/reference/events-that-trigger-workflows" target="_blank">公式ドキュメント</a>をご参照ください。</p>
  </li>
  <li>
    <p>基本的にすべての CI/CD や自動化で遭遇するイベントシナリオを網羅しています。<br />
しかし、<strong>特殊なシナリオでイベントがない場合は、他のイベントと組み合わせて Job 内で判定するか、Schedule を使って手動でチェックするしかありません</strong>。<br />
例：PR Merged イベントがない場合は、<code class="language-plaintext highlighter-rouge">pull_request: closed</code> と Job の <code class="language-plaintext highlighter-rouge">if: github.event.pull_request.merged == true</code> を使って実現します。</p>
  </li>
</ul>

<p><strong>よく使われるイベント：</strong></p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">schedule</code> (cron)：スケジュールによる定期実行（crontab と同様）<br />
自動化に利用可能：定期的な PR チェック、定期ビルド、定期的な自動化スクリプトの実行など<br />
<strong>すべて main / develop（デフォルトブランチ）で実行されます。</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">pull_request:</code> ：PR 関連のイベント<br />
PR がオープンされたとき、PR がアサインされたとき、ラベルが追加されたとき、新しいコミットがプッシュされたとき…など</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">issues</code> 、 <code class="language-plaintext highlighter-rouge">issue_comment</code> ：Issue に関連するイベント<br />
Issue が作成されたとき、新しいコメントが追加されたとき…など</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">workflow_dispatch</code> ：手動トリガー；入力が必要なフィールドを設定でき、GitHub Actions はユーザーが情報を入力できる簡単なフォームを提供します。<br />
e.g.:</p>
  </li>
</ul>

<p><img src="/assets/404bd5c70040/1*XogIJsCbrNPerWBto_PG8w.webp" alt="" loading="lazy" decoding="async" width="332" height="432" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMzIiIGhlaWdodD0iNDMyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*XogIJsCbrNPerWBto_PG8w.png" /></p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">workflow_call</code> ：別の Action（Workflow）を呼び出してタスクを実行します。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">workflow_run</code> ：他の Action（Workflow）がタスクを実行したときに、このタスクをトリガーします。</p>
  </li>
</ul>

<blockquote>
  <p><em>さらに多くのイベントタイプや設定の詳細は<a href="https://docs.github.com/en/actions/reference/events-that-trigger-workflows" target="_blank">公式ドキュメント</a>をご参照ください。</em></p>
</blockquote>

<h4 id="github-actions--ワークフロー"><strong>GitHub Actions — ワークフロー</strong></h4>

<ul>
  <li>
    <p>別名 Action</p>
  </li>
  <li>
    <p>YAML を使って .yaml ファイルを作成し、ファイルはすべて <code class="language-plaintext highlighter-rouge">REPO/.github/workflows/</code> に配置します。</p>
  </li>
  <li>
    <p><strong>メインブランチ内の Workflow YAML ファイルを基準にする</strong><br />
他のブランチで開発中の Action が見えない場合や実行に問題がある場合は、まずメインブランチにマージして確認してください。</p>
  </li>
  <li>
    <p>GitHub Actions の最も基本的な単位である Workflow は、それぞれ CI/CD や自動化操作を表します。</p>
  </li>
  <li>
    <p>Workflow は他の Workflow を呼び出してタスクを実行できる<br />
（この特性を利用して、コア Workflow と呼び出し用の Workflow を分けることができます）</p>
  </li>
  <li>
    <p>ここでは、タスク名、実行戦略、トリガーイベント、タスクのジョブなど、すべての Action に関する設定を定義します。</p>
  </li>
  <li>
    <p>現在のファイル構成はサブディレクトリをサポートしていません。</p>
  </li>
  <li>
    <p>Action は完全無料（パブリックおよびプライベートリポジトリ）</p>
  </li>
</ul>

<h4 id="github-actions--ワークフロー--ジョブ">GitHub Actions — ワークフロー — ジョブ</h4>

<ul>
  <li>
    <p>GitHub Actions における実行単位</p>
  </li>
  <li>
    <p>Workflow 内のジョブにはどのようなものがあるか定義する</p>
  </li>
  <li>
    <p>各 Workflow は複数の Jobs を持つことができます</p>
  </li>
  <li>
    <p>各ジョブは使用する Runner ラベルを指定する必要があり、実行時には対応する Runner マシンでタスクが実行されます。</p>
  </li>
  <li>
    <p><strong>複数のジョブは並行実行されます</strong>（順序が必要な場合は <code class="language-plaintext highlighter-rouge">needs</code> で制約可能）</p>
  </li>
  <li>
    <p><strong>各ジョブは独立した実行単位（それぞれをサンドボックスとして扱う）</strong> と考えるべきであり、ジョブ終了後に生成されたリソースファイルを他のジョブやワークフローで使用する場合は、Artifacts をアップロードするか、self-hosted 環境で共有出力ディレクトリに移動する必要があります。</p>
  </li>
  <li>
    <p>Job が完了すると、他の Job が参照できる文字列を Output として渡せます。<br />
（例：実行結果 true または false）</p>
  </li>
  <li>
    <p>特にワークフロー条件を設定していない場合、複数の Job のうち一つの Job がエラーになっても、<strong>他の Job は引き続き実行されます</strong>。</p>
  </li>
</ul>

<h4 id="github-actions--ワークフロージョブの再利用">GitHub Actions — ワークフロー/ジョブの再利用</h4>

<ul>
  <li>
    <p>Workflow 定義で <code class="language-plaintext highlighter-rouge">on: workflow_call</code> を指定すると、他の Workflow に Job として再利用可能な形でパッケージ化できます。</p>
  </li>
  <li>
    <p>同じ組織内でリポジトリを跨いで共有可能です。</p>
  </li>
  <li>
    <p>そのため、複数のリポジトリで共通の CI/CD ワークフローを共有リポジトリにまとめて利用できます。</p>
  </li>
</ul>

<h4 id="github-actions--ワークフロー--ジョブ--ステップ">GitHub Actions — ワークフロー — ジョブ — ステップ</h4>

<ul>
  <li>
    <p>GitHub Actions における最小実行単位</p>
  </li>
  <li>
    <p>Job 内で実際にタスクを実行するプログラム</p>
  </li>
  <li>
    <p>各ジョブは複数のステップを持つことができます</p>
  </li>
  <li>
    <p><strong>複数の Steps は順番に実行されます</strong></p>
  </li>
  <li>
    <p>Step が完了すると、後続の Steps が参照できる文字列を出力できます。</p>
  </li>
  <li>
    <p><strong>Step は直接 shell script を記述可能</strong><br />
<a href="https://cli.github.com/manual/gh" target="_blank">gh cli</a> や現在の環境変数（例：PR番号の取得）を利用して、やりたいことを直接実行できます。</p>
  </li>
  <li>
    <p>特にフロー条件を設定していない場合、Stepでエラーが発生すると<strong>直ちに中断</strong>され、後続のStepsは実行されません。</p>
  </li>
</ul>

<h4 id="github-actions--ワークフロー--ジョブ--アクションステップの再利用">GitHub Actions — ワークフロー — ジョブ — アクションステップの再利用</h4>

<ul>
  <li>
    <p><strong><a href="https://github.com/marketplace?type=actions" target="_blank">Marketplace</a> にある多くの優れた既存ワークフローをそのまま再利用できます。</strong><br />
例えば、<a href="https://github.com/marketplace/actions/comment-pull-request" target="_blank">PRにコメントを投稿</a> などがあります。</p>
  </li>
  <li>
    <p>自分の一連の作業ステップをまとめて、他のワークフローで直接再利用できる Action GitHub リポジトリとしてパッケージ化することも可能です。</p>
  </li>
  <li>
    <p>Public Repo の Action は Marketplace に公開できます。</p>
  </li>
</ul>

<p><strong>パッケージ化された Action のサポート：</strong></p>

<ul>
  <li>
    <p><strong>Docker Action</strong> — GitHub Actions は環境変数を Docker コンテナに渡し、その後 shell script、Java、PHP などで処理します。</p>
  </li>
  <li>
    <p><strong>JavaScript/TypeScript Action</strong> — node.js を使って直接 GitHub Actions の処理ロジックを作成します。環境変数もすべて参照用に渡されます。<br />
例: <a href="https://github.com/pozil/auto-assign-issue/blob/v2/action.yml" target="_blank">pozil/auto-assign-issue</a></p>
  </li>
  <li>
    <p><strong>Composite (YAML) —</strong> 純粋な YAML でタスクのステップを記述します（GitHub Actions の Workflow — Job — Step と同様）。実行するステップを宣言したり、直接シェルスクリプトを書くことができます。<br />
例: <a href="https://github.com/ZhgChgLi/ZReviewTender/blob/main/action.yml" target="_blank">ZhgChgLi/ZReviewTender</a></p>
  </li>
</ul>

<blockquote>
  <p><em>ページの都合上、本記事では GitHub Actions の Action 作成方法については紹介しません。興味がある方は公式ドキュメントをご参照ください： <a href="https://docs.github.com/en/actions/tutorials/creating-a-composite-action" target="_blank">tutorials/creating-a-composite-action</a> 。</em></p>
</blockquote>

<h4 id="github-runner">GitHub Runner</h4>

<ul>
  <li>
    <p>GitHub は Runner Label に基づいて対応するジョブを Runner に割り当てて実行します。</p>
  </li>
  <li>
    <p>Runner はリスナーとしてのみ機能し、GitHub からのタスクをポーリングして監視します。</p>
  </li>
  <li>
    <p>Job のみを重視し、どの Action（Workflow）かは気にしません。<br />
そのため、Action A の Job-1 が完了したら、次に Action B の Job-1 が実行され、Action A のすべての Jobs が完了してから Action B に移るわけではありません。</p>
  </li>
  <li>
    <p>Runner は GitHub Hosted Runner または Self-hosted Runner を使用できます。</p>
  </li>
</ul>

<h4 id="github-ホスト型ランナー"><strong>GitHub ホスト型ランナー</strong></h4>

<ul>
  <li>GitHub が提供する Runner は、公式リポジトリ一覧を参照してください：</li>
</ul>

<p><a href="https://github.com/actions/runner-images" target="_blank"><img src="https://opengraph.githubassets.com/752d8c5522e9674fddc4c85962169e07ac91e262e2e3bd299cccec91a8f20b26/actions/runner-images" alt="" /></a></p>

<p><img src="/assets/404bd5c70040/1*KtQV4kDCWscEeaZ8jQI8Dg.webp" alt="2025/06 の Images リスト" loading="lazy" decoding="async" width="1200" height="1154" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjExNTQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/404bd5c70040/1*KtQV4kDCWscEeaZ8jQI8Dg.png" /></p>

<p><a href="https://github.com/actions/runner-images" target="_blank">2025/06 の Images リスト</a></p>

<ul>
  <li>Runner にあらかじめインストールされているものは以下から確認できます：<br />
例：<a href="https://github.com/actions/runner-images/blob/main/images/macos/macos-14-arm64-Readme.md" target="_blank">macos-14-arm64</a></li>
</ul>

<p><img src="/assets/404bd5c70040/1*svXtXH78-TvK1C_XXCyYLA.webp" alt="macos-14-arm64" loading="lazy" decoding="async" width="1200" height="669" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY2OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*svXtXH78-TvK1C_XXCyYLA.png" /></p>

<p><a href="https://github.com/actions/runner-images/blob/main/images/macos/macos-14-arm64-Readme.md" target="_blank">macos-14-arm64</a></p>

<ul>
  <li>
    <p>iOS開発では、-arm64（Mシリーズ）プロセッサのランナーを優先的に使用すると、より高速に動作します。</p>
  </li>
  <li>
    <p>Job の <code class="language-plaintext highlighter-rouge">runs-on</code> に表の YAML ラベルを貼り付けるだけで、そのRunnerを使ってジョブを実行できます。</p>
  </li>
  <li>
    <p><strong>Public Repo の料金体系：完全無料で無制限に利用可能</strong></p>
  </li>
  <li>
    <p><strong>️</strong> Private Repo 無料枠:<br />
無料枠（アカウントによって異なりますが、GitHub Free の場合を例とします）：<br />
使用量：毎月無料 2,000 分<br />
ストレージ：500 MB</p>
  </li>
  <li>
    <p><strong>⚠️️Private Repo の課金方法：</strong><br />
<strong>無料枠を超えると従量課金が始まります（上限設定や通知可能）。Runnerが動作するマシンのOSやコア数によって料金が異なります：</strong></p>
  </li>
</ul>

<p><img src="/assets/404bd5c70040/1*rkhRJN4ZRas_lDOJh-pjkQ.webp" alt="about-billing-for-github-actions" loading="lazy" decoding="async" width="1064" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDY0IiBoZWlnaHQ9IjEyMDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/404bd5c70040/1*rkhRJN4ZRas_lDOJh-pjkQ.png" /></p>

<p><a href="https://docs.github.com/en/billing/managing-billing-for-your-products/about-billing-for-github-actions" target="_blank">about-billing-for-github-actions</a></p>

<p>macOS の価格は、デバイスのコストが高いため高価であることがわかります。</p>

<ul>
  <li>最大同時実行ジョブ数の制限：</li>
</ul>

<p><img src="/assets/404bd5c70040/1*LU3zGSBe57NBVMfDwl0wdQ.webp" alt="usage-limits-billing-and-administration" loading="lazy" decoding="async" width="1200" height="490" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjQ5MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*LU3zGSBe57NBVMfDwl0wdQ.png" /></p>

<p><a href="https://docs.github.com/en/actions/concepts/overview/usage-limits-billing-and-administration#usage-limits" target="_blank">usage-limits-billing-and-administration</a></p>

<blockquote>
  <p><em>ここでは話がそれすぎています。私たちの重点は Self-hosted Runner です。</em></p>
</blockquote>

<h4 id="社内サーバーでのセルフホストランナー">社内サーバーでのセルフホストランナー</h4>

<ul>
  <li>
    <p>自分のマシンを Runner として使用する</p>
  </li>
  <li>
    <p><strong>1台の実機で複数のRunnerを起動し、並行してジョブを処理できる</strong></p>
  </li>
  <li>
    <p><strong>無料で無制限に使用可能</strong><br />
機器の購入費用のみで、一度購入すれば使い放題！<br />
32G RAM M4 Mini（=NT$40,900）を例にすると、GitHub Hosted Runner を使うと1ヶ月で500 USDかかりますが、<strong>1台購入してセットアップすれば3ヶ月以上で元が取れます</strong>！</p>
  </li>
  <li>
    <p>Windows、macOS、Linux (x64/ARM/ARM64) をサポートしています</p>
  </li>
  <li>
    <p><strong>同じ組織内で複数のリポジトリ間で Runner を共有可能</strong></p>
  </li>
  <li>
    <p><strong>⚠️現在：actions/cache、actions/upload-artifact、actions/download-artifact はすべて GitHub のクラウドサービスのみ対応しており、これらのデータは GitHub サーバーにアップロードされ、ストレージ使用量に応じて課金されます。</strong><br />
自分のマシン上で共有ディレクトリを作成して代替することが可能です。</p>
  </li>
  <li>
    <p>Self-hosted Runner は <a href="https://docs.github.com/en/actions/concepts/runners/about-actions-runner-controller" target="_blank">Docker, k8s</a> もサポートしていますが、私はまだ調べていません。</p>
  </li>
</ul>

<blockquote>
  <p><strong><em>Self-hosted Runner のセットアップは数ステップで完了し（10分以内に設定可能）、すぐにタスクの実行を開始できます（本文の後半で詳しく説明します）。</em></strong></p>
</blockquote>

<h4 id="github-workflow-x-job-x-step-x-runner-フロー関係図">GitHub Workflow x Job x Step x Runner フロー関係図</h4>

<p><img src="/assets/404bd5c70040/1*WHIVfXdVRoEsdXGfJhu2Rw.webp" alt="" loading="lazy" decoding="async" width="1400" height="852" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijg1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*WHIVfXdVRoEsdXGfJhu2Rw.png" /></p>

<p>ここでは図を使ってワークフローと関係をまとめます。ワークフローが2つ、ランナーが2つあると仮定します：</p>

<ul>
  <li>
    <p>CI — Rには3つのジョブがあり、それぞれのジョブに複数のステップがあります。Runner Label(run-on) — <code class="language-plaintext highlighter-rouge">self-hosted-app</code></p>
  </li>
  <li>
    <p>CD — 4つのジョブがあり、それぞれのジョブにいくつかのステップがあります。Runner Label(run-on) — <code class="language-plaintext highlighter-rouge">self-hosted-app</code></p>
  </li>
  <li>
    <p>Runner — 2つあり、Runner Label はどちらも <code class="language-plaintext highlighter-rouge">self-hosted-app</code> です</p>
  </li>
</ul>

<p>前述の通り、Runner と Workflow は Runner Label に基づいてタスクの割り当てや受け取りを行います。このケースではすべて同じ <code class="language-plaintext highlighter-rouge">self-hosted-app</code> Runner Label を使用しています。Workflow の Jobs はデフォルトで並行実行され、Steps は各 Job の実際の処理内容であり、順番に直列実行されます。すべての Steps が完了すると Job も完了となります。</p>

<blockquote>
  <p><strong><em>そのため、Workflow の実際の実行タイムラインは、2つの Runner 間を行き来して Job を実行し、並行して実行されることもあり、現在の Job が終了しても次に実行されるのが必ずしも同じ Workflow の次の Job とは限りません。</em></strong></p>
</blockquote>

<blockquote>
  <p><em>⚠️ だからこそ、各ジョブが独立していることを確認することが重要です（特に Self-hosted Runner 環境では、ジョブ終了後にクリーンアップが十分に行われない場合があり、そのジョブの成果物を次のジョブでそのまま使えると思い込んでしまうことがあります）が、そのように使うべきではありません。</em></p>
</blockquote>

<h4 id="job-が後続の-job-に成果物を渡す場合">Job が後続の Job に成果物を渡す場合:</h4>

<ul>
  <li>
    <p><strong>Job Output String</strong> : 他のジョブで参照するために変数へプレーンテキストを出力する</p>
  </li>
  <li>
    <p><strong>Artifact-upload/download:</strong> ジョブの最後のステップで実行結果を GitHub Artifact にアップロードし、別のジョブの最初のステップでダウンロードして処理を続けます。<br />
例：ジョブ — パッケージ → パッケージ結果の .ipa を <strong>Artifact →</strong> ジョブ — デプロイ → .ipa をダウンロード → App Store にアップロードしてデプロイ<br />
注意点：<strong>現在、Self-hosted でも GitHub Artifact はクラウドストレージに保存されます。</strong></p>
  </li>
  <li>
    <p><strong>AWS/GCP…クラウドストレージ</strong> : 同様ですが、自分のクラウドストレージサービスを使用します。</p>
  </li>
  <li>
    <p><strong>[Self-hosted Only] 共有ドライブ、ディレクトリ:</strong> Self-hosted Runner が共通のディレクトリをマウントしている場合、このディレクトリ内に UUID ごとにフォルダを作成して成果物を保存できます。その後のジョブは前のジョブの Output UUID を使って対応する保存場所を参照し、データを取得して利用します。<br />
注意点として、異なるホストの Runner も同じ共有ディレクトリをマウントしている必要があります。</p>
  </li>
  <li>
    <p>同じジョブのステップで全ての作業を完了させる。</p>
  </li>
</ul>

<h3 id="実践で学ぶ-github-actions--ケーススタディ">実践で学ぶ GitHub Actions — ケーススタディ</h3>

<p>「言うより行う」この言葉の意味やプロセス構成の説明は皆さんも少し曖昧に感じていると思います。次に、実際に3つの機能例を挙げて、一緒に手を動かしながら解説していきます。実践しながら学ぶことで、GitHub Actionsが何かを理解していきましょう。</p>

<h3 id="ケース--1">ケース — 1</h3>

<p>Pull Request 作成後にファイル変更のサイズラベルを自動で付けて、レビュアーがレビュー作業をスムーズに行えるようにします。</p>

<h4 id="成果図">成果図</h4>

<p><img src="/assets/404bd5c70040/1*vjSWeu2zB-hmVpfziMDR5Q.webp" alt="Demo PR" loading="lazy" decoding="async" width="774" height="206" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzQiIGhlaWdodD0iMjA2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*vjSWeu2zB-hmVpfziMDR5Q.png" /></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/pull/11" target="_blank">Demo PR</a></p>

<h4 id="動作の流れ">動作の流れ</h4>

<ul>
  <li>
    <p>ユーザーが PR を作成、再オープン、または PR に新しいコミットをプッシュしたとき</p>
  </li>
  <li>
    <p>GitHub Actions のワークフローをトリガーする</p>
  </li>
  <li>
    <p>shell script でファイルの変更数を取得する方法</p>
  </li>
  <li>
    <p>PR のラベルを変更数に応じて付ける</p>
  </li>
  <li>
    <p>完了</p>
  </li>
</ul>

<h4 id="実践してみよう">実践してみよう</h4>

<p>Repo → Actions → New workflow → 自分でワークフローを設定する。</p>

<p><strong>ファイル名：</strong> <code class="language-plaintext highlighter-rouge">Automation-PullRequest.yml</code></p>

<p>Action Workflow はタスクごとにファイルを分けることも、トリガーイベントや目的に応じて同じ目的のものを1つのファイルにまとめることもできます。いずれにせよ複数の Job は並行して実行されます。なお、<strong>GitHub Actions は現時点でディレクトリ構造をサポートしていないため、ファイル数を少なくし、階層的な命名を使った方が管理しやすいです</strong>。</p>

<p>ここでは PR 関連のイベントの Actions をすべて同じ Workflow にまとめています。</p>

<h4 id="automation-pullrequestyml"><code class="language-plaintext highlighter-rouge">Automation-PullRequest.yml</code></h4>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Workflow(Action) 名称</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">Pull Reqeust Automation</span>

<span class="c1"># Actions ログのタイトル名</span>
<span class="na">run-name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">[Pull</span><span class="nv"> </span><span class="s">Reqeust</span><span class="nv"> </span><span class="s">Automation]</span><span class="nv"> </span><span class="s">${{</span><span class="nv"> </span><span class="s">github.event.pull_request.title</span><span class="nv"> </span><span class="se">\\</span><span class="s">|</span><span class="se">\\</span><span class="s">|</span><span class="nv"> </span><span class="s">github.ref</span><span class="nv"> </span><span class="s">}}"</span>

<span class="c1"># トリガーイベント</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># PR イベント</span>
  <span class="na">pull_request</span><span class="pi">:</span>
    <span class="c1"># PR - オープン、再オープン、新しい Push Commit 時</span>
    <span class="na">types</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">opened</span><span class="pi">,</span> <span class="nv">synchronize</span><span class="pi">,</span> <span class="nv">reopened</span><span class="pi">]</span>


<span class="c1"># 同じ Concurrency Group に新しい Job がある場合、実行中のものをキャンセル</span>
<span class="c1"># 例えば Push Commit でトリガーされたジョブがまだ実行中に再度 Push Commit があった場合、前のジョブをキャンセル</span>
<span class="na">concurrency</span><span class="pi">:</span>
  <span class="na">group</span><span class="pi">:</span> <span class="s">${{ github.workflow }}-${{ github.ref_name }}</span>
  <span class="na">cancel-in-progress</span><span class="pi">:</span> <span class="kc">true</span>

<span class="c1"># Job 作業項目</span>
<span class="c1"># Job は並行実行される</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="c1"># Job ID</span>
  <span class="na">label-pr-by-file-count</span><span class="pi">:</span>
    <span class="c1"># Job 名称（省略可、ログに表示され読みやすくなる）</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">Label PR by changes file count</span>

    <span class="c1"># この Job が失敗しても Workflow 全体には影響せず、他の Job は続行</span>
    <span class="na">continue-on-error</span><span class="pi">:</span> <span class="kc">true</span>
    
    <span class="c1"># 最大タイムアウト時間を設定し、異常時の無限待機を防止</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">10</span>

    <span class="c1"># Runner ラベル - GitHub Hosted Runner の ubuntu-latest を使用して実行</span>
    <span class="c1"># Private Repo の場合は使用量が計算され、超過すると費用が発生する可能性あり</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>

    <span class="c1"># 作業ステップ</span>
    <span class="c1"># ステップは順番に実行される</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="c1"># ステップ名</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Get changed file count and apply label</span>
        <span class="c1"># ステップ ID（省略可、後で Step の Output を参照しない場合は不要）</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">get-changed-files-count-by-gh</span>
        <span class="c1"># 外部環境変数を実行時に注入</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="c1"># secrets.GITHUB_TOKEN は GitHub Actions 実行時に自動生成されるトークンで、Secrets に設定不要</span>
          <span class="c1"># 一部の GitHub Repo API スコープの権限を持つ</span>
          <span class="c1"># https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows</span>
          <span class="c1"># gh(GitHub) cli は GH_TOKEN を ENV に注入する必要があり、gh が操作権限を持つ</span>
          <span class="na">GH_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.GITHUB_TOKEN }}</span>
        <span class="c1"># シェルスクリプト</span>
        <span class="c1"># GitHub Hosted Runner には gh cli があらかじめインストール済みで、インストール不要で使用可能</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">#   ${{ github.xxx }} は GitHub Actions の Context 式</span>
          <span class="s">#   シェル変数ではなく、YAML 解析時に GitHub Actions によって対応する値に置換される</span>
          <span class="s">#   その他のパラメータ：https://docs.github.com/en/actions/learn-github-actions/contexts#github-context</span>
          
          <span class="s"># PR 番号を取得</span><span class="err">:</span>
          <span class="s">PR_NUMBER=${{ github.event.pull_request.number }}</span>

          <span class="s"># リポジトリを取得</span><span class="err">:</span>
          <span class="s">REPO=${{ github.repository }}</span>

          <span class="s"># GitHub API (gh cli) で変更ファイル数を取得</span>
          <span class="s">FILE_COUNT=$(gh pr view $PR_NUMBER --repo $REPO --json files --jq '.files \\| length')</span>
          
          <span class="s"># ログ出力</span>
          <span class="s">echo "Changed file count</span><span class="err">:</span> <span class="s">$FILE_COUNT"</span>

          <span class="s"># ラベル付けロジック</span>
          <span class="s">if [ "$FILE_COUNT" -lt 5 ]; then</span>
            <span class="s">LABEL="XS"</span>
          <span class="s">elif [ "$FILE_COUNT" -lt 10 ]; then</span>
            <span class="s">LABEL="S"</span>
          <span class="s">elif [ "$FILE_COUNT" -lt 30 ]; then</span>
            <span class="s">LABEL="M"</span>
          <span class="s">elif [ "$FILE_COUNT" -lt 80 ]; then</span>
            <span class="s">LABEL="L"</span>
          <span class="s">elif [ "$FILE_COUNT" -lt 200 ]; then</span>
            <span class="s">LABEL="XL"</span>
          <span class="s">else</span>
            <span class="s">LABEL="XXL"</span>
          <span class="s">fi</span>

          <span class="s"># GitHub API (gh cli) で現在のサイズラベルを削除</span>
          <span class="s">EXISTING_LABELS=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json labels --jq '.labels[].name')</span>
          <span class="s">for EXISTING in $EXISTING_LABELS; do</span>
            <span class="s">case "$EXISTING" in</span>
              <span class="s">XS\\|S\\|M\\|L\\|XL\\|XXL)</span>
                <span class="s">echo "🧹 既存ラベルを削除中</span><span class="err">:</span> <span class="s">$EXISTING"</span>
                <span class="s">gh pr edit "$PR_NUMBER" --repo "$REPO" --remove-label "$EXISTING"</span>
                <span class="s">;;</span>
            <span class="s">esac</span>
          <span class="s">done</span>

          <span class="s"># （任意）ラベルが存在しなければ作成</span>
          <span class="s">if ! gh label list --repo "$REPO" \\| grep -q "^$LABEL"; then</span>
            <span class="s">echo "🆕 ラベルを作成中</span><span class="err">:</span> <span class="s">$LABEL"</span>
            <span class="s">gh label create "$LABEL" --repo "$REPO" --description "Size label</span><span class="err">:</span> <span class="s">$LABEL" --color "ededed"</span>
          <span class="s">else</span>
            <span class="s">echo "✅ ラベル '$LABEL' は既に存在します"</span>
          <span class="s">fi</span>
          
          <span class="s"># GitHub API (gh cli) でラベルを付与</span>
          <span class="s">gh pr edit $PR_NUMBER --repo $REPO --add-label "$LABEL"</span>
</code></pre></div></div>

<p>Commit ファイルをリポジトリのメインブランチにプッシュした後、新しい PR を作成すると自動的に GitHub Actions がトリガーされます：</p>

<p><img src="/assets/404bd5c70040/1*wdAztL0BgPeSZdqXxqUEXg.webp" alt="" loading="lazy" decoding="async" width="938" height="744" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzgiIGhlaWdodD0iNzQ0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*wdAztL0BgPeSZdqXxqUEXg.png" /></p>

<p>Action の実行状態が <strong>Queued</strong> となっている場合、タスクが Runner に引き継がれて実行されるのを待っていることを意味します。</p>

<h4 id="実行結果">実行結果</h4>

<p><img src="/assets/404bd5c70040/1*-JoD8IQYHVrDqHmLmrXyaQ.webp" alt="Demo PR" loading="lazy" decoding="async" width="1338" height="948" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzM4IiBoZWlnaHQ9Ijk0OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*-JoD8IQYHVrDqHmLmrXyaQ.png" /></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/pull/11" target="_blank">Demo PR</a></p>

<p>実行が完了し成功すると、PR に対応するラベルが自動で付けられます！記録には <code class="language-plaintext highlighter-rouge">github-actions</code> がラベル付けしたことが表示されます。</p>

<p><strong>完全なコード： <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/Automation-PullRequest.yml" target="_blank">Automation-PullRequest.yml</a></strong></p>

<h4 id="他人が作成した-action-を直接使用する手順-pascalgnsize-label-action">他人が作成した Action を直接使用する手順： <a href="https://github.com/pascalgn/size-label-action/tree/main" target="_blank">pascalgn/size-label-action</a></h4>

<p>前述で他人が作成したActionを直接使えると説明しましたが、PRのサイズラベルを付けるタスクにはすでに使えるツールがあります。上記はあくまで教育目的であり、実際には自分で作り直す必要はありません。</p>

<p>Action Workflow Job Step 内で直接使用するだけでタスクを完了できます：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Workflow(Action) 名称</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">Pull Reqeust Automation</span>

<span class="c1"># トリガーイベント</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># PRイベント</span>
  <span class="na">pull_request</span><span class="pi">:</span>
    <span class="c1"># PR - オープン、再オープン、新しいPushコミットがある時</span>
    <span class="na">types</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">opened</span><span class="pi">,</span> <span class="nv">synchronize</span><span class="pi">,</span> <span class="nv">reopened</span><span class="pi">]</span>


<span class="c1"># 同じConcurrency Group内で新しいJobが開始されると、実行中のJobはキャンセルされる</span>
<span class="c1"># 例えばPushコミットでトリガーされたジョブがまだ実行されていないのに、さらにPushコミットがある場合、前のジョブをキャンセルする</span>
<span class="na">concurrency</span><span class="pi">:</span>
  <span class="na">group</span><span class="pi">:</span> <span class="s">${{ github.workflow }}-${{ github.ref_name }}</span>
  <span class="na">cancel-in-progress</span><span class="pi">:</span> <span class="kc">true</span>

<span class="c1"># Jobの作業項目</span>
<span class="c1"># Jobは並行して実行される</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="c1"># Job ID</span>
  <span class="na">label-pr-by-file-count</span><span class="pi">:</span>
    <span class="c1"># Job名（省略可能。ログ表示のために設定推奨）</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">Label PR by changes file count</span>

    <span class="c1"># このJobが失敗してもWorkflow全体には影響せず、他のJobを続行する</span>
    <span class="na">continue-on-error</span><span class="pi">:</span> <span class="kc">true</span>
    
    <span class="c1"># 最大タイムアウト時間を設定し、異常時の無限待機を防ぐ</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">10</span>

    <span class="c1"># Runnerラベル - GitHubホストランナーのubuntu-latestを使用して作業を実行</span>
    <span class="c1"># Privateリポジトリの場合は使用量がカウントされ、超過すると費用が発生する可能性あり</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>

    <span class="c1"># 作業ステップ</span>
    <span class="c1"># ステップは順番に実行される</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="c1"># ステップ名</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Get changed file count and apply label</span>
        <span class="c1"># ステップID（省略可能。後続のステップでOutputを参照しない場合は不要）</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">get-changed-files-count-by-gh</span>
        <span class="c1"># 他者が作成したアクションを直接利用</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s2">"</span><span class="s">pascalgn/size-label-action@v0.5.5"</span>
        <span class="c1"># 外部環境パラメータを実行時に注入</span>
        <span class="c1"># パラメータ名や使用可能なパラメータは説明を参照：https://github.com/pascalgn/size-label-action/tree/main</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="c1"># secrets.GITHUB_TOKENはGitHub Actions実行時に自動生成されるトークン（github-actionsのID）、Secretsに自分で設定不要で、GitHubリポジトリのAPIスコープ権限を持つ</span>
          <span class="c1"># https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows</span>
          <span class="na">GITHUB_TOKEN</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">secrets.GITHUB_TOKEN</span><span class="nv"> </span><span class="s">}}"</span>
</code></pre></div></div>

<p><a href="https://github.com/pascalgn/size-label-action/tree/main" target="_blank"><img src="https://opengraph.githubassets.com/746d87e558bda612364f12277484f99cae4c57fbb2eb910bfd59d6865c1b6e94/pascalgn/size-label-action" alt="" /></a></p>

<p>このパッケージ化された Action は JavaScript Action であり、実際の実行コードは以下のファイルを参照してください： <a href="https://github.com/pascalgn/size-label-action/blob/main/dist/index.js" target="_blank">dist/index.js</a> 。</p>

<h4 id="name-run-name-の補足">name, run-name の補足：</h4>

<p><img src="/assets/404bd5c70040/1*zBmjm_3AU53NN0UhTrmOBQ.webp" alt="" loading="lazy" decoding="async" width="1012" height="569" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDEyIiBoZWlnaHQ9IjU2OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*zBmjm_3AU53NN0UhTrmOBQ.png" /></p>

<ul>
  <li>
    <p>name: Action Workflow の名前</p>
  </li>
  <li>
    <p>run-name: 実行ログのタイトル名（PRタイトルやブランチ、作成者などを指定可能）<br />
on: pull_request イベントの場合、デフォルトは PR タイトルです。</p>
  </li>
</ul>

<h3 id="ケース--2">ケース — 2</h3>

<p>Pull Request を作成後、Assignee が設定されていなければ自動的に作成者を Assign し、コメントで通知します。（初回作成時のみ実行）</p>

<h4 id="成果図-1">成果図</h4>

<p><img src="/assets/404bd5c70040/1*EL-0nQF7jhP34d6ZoSkJAg.webp" alt="Demo PR" loading="lazy" decoding="async" width="1200" height="682" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY4MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*EL-0nQF7jhP34d6ZoSkJAg.png" /></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/pull/11" target="_blank">Demo PR</a></p>

<h4 id="動作の流れ-1">動作の流れ</h4>

<ul>
  <li>
    <p>ユーザーがPRを作成する</p>
  </li>
  <li>
    <p>GitHub Actions Workflowをトリガーする</p>
  </li>
  <li>
    <p>github scriptでassigneeを取得する方法</p>
  </li>
  <li>
    <p>アサインがない場合、PRの作成者をアサインしてコメントを追加する</p>
  </li>
  <li>
    <p>完了</p>
  </li>
</ul>

<h4 id="実践してみよう-1">実践してみよう</h4>

<p>Repo → Actions → New workflow → 自分でワークフローを設定する。</p>

<p><strong>ファイル名：</strong> <code class="language-plaintext highlighter-rouge">Automation-PullRequest.yml</code> (同上)</p>

<h4 id="automation-pullrequestyml-1"><code class="language-plaintext highlighter-rouge">Automation-PullRequest.yml</code></h4>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Workflow(Action) 名称</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">Pull Reqeust Automation</span>

<span class="c1"># Actions ログのタイトル名</span>
<span class="na">run-name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Pull</span><span class="nv"> </span><span class="s">Reqeust</span><span class="nv"> </span><span class="s">Automation</span><span class="nv"> </span><span class="s">-</span><span class="nv"> </span><span class="s">Daily</span><span class="nv"> </span><span class="s">Checker"</span>

<span class="c1"># トリガーイベント</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># PR イベント</span>
  <span class="na">pull_request</span><span class="pi">:</span>
    <span class="c1"># PR - オープン、再オープン、新しい Push Commit 時</span>
    <span class="na">types</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">opened</span><span class="pi">,</span> <span class="nv">synchronize</span><span class="pi">,</span> <span class="nv">reopened</span><span class="pi">]</span>


<span class="c1"># 同じ Concurrency Group に新しい Job がある場合、実行中のものをキャンセル</span>
<span class="c1"># 例えば Push Commit トリガーのジョブがまだ実行されていないのに再度 Push Commit された場合、前のジョブをキャンセル</span>
<span class="na">concurrency</span><span class="pi">:</span>
  <span class="na">group</span><span class="pi">:</span> <span class="s">${{ github.workflow }}-${{ github.ref_name }}</span>
  <span class="na">cancel-in-progress</span><span class="pi">:</span> <span class="kc">true</span>

<span class="c1"># Job 作業項目</span>
<span class="c1"># Job は並行実行される</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="c1"># Job ID</span>
  <span class="na">label-pr-by-file-count</span><span class="pi">:</span>
    <span class="c1"># 前文を参照、略....</span>
  <span class="c1"># ---------</span>
  <span class="na">assign-self-if-no-assignee</span><span class="pi">:</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">Automatically assign to self if no assignee is specified</span>
    <span class="c1"># 共通トリガーのため、Job 内で自分で判定。Pull Request Opened（初回作成）のみ実行し、それ以外はスキップ</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">github.event_name == 'pull_request' &amp;&amp; github.event.action == 'opened'</span>

    <span class="c1"># この Job が失敗しても Workflow 全体に影響せず、他の Job を継続</span>
    <span class="na">continue-on-error</span><span class="pi">:</span> <span class="kc">true</span>
    
    <span class="c1"># 最長タイムアウト時間を設定し、異常時の無限待機を防止</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">10</span>
    
    <span class="c1"># Runner Label - GitHub Hosted Runner の ubuntu-latest を使用して作業を実行</span>
    <span class="c1"># Private Repo の場合は使用量が計算され、超過すると料金が発生する可能性あり</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Assign self if No Assignee</span>
        <span class="c1"># GitHub Script (JavaScript) でスクリプト作成 (Node.js 環境)</span>
        <span class="c1"># 直接 Shell Script より便利で見やすい</span>
        <span class="c1"># 環境変数や GITHUB_TOKEN の注入も不要</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/github-script@v7</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">script</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">// github-script では context 変数が自動的に注入され、JavaScript で直接参照可能</span>
            <span class="s">// https://docs.github.com/en/actions/learn-github-actions/contexts#github-context</span>

            <span class="s">const issue = context.payload.pull_request; // Issue も対応する場合は context.payload.issue \\|\\| context.payload.pull_request と記述可能</span>
            <span class="s">const assignees = issue.assignees \\|\\| [];</span>
            <span class="s">const me = context.actor;</span>

            <span class="s">if (assignees.length === 0) {</span>
              <span class="s">// Assignee を自分に設定</span>
              <span class="s">await github.rest.issues.addAssignees({</span>
                <span class="s">owner</span><span class="err">:</span> <span class="s">context.repo.owner,</span>
                <span class="s">repo</span><span class="err">:</span> <span class="s">context.repo.repo,</span>
                <span class="s">issue_number</span><span class="err">:</span> <span class="s">issue.number,</span>
                <span class="s">assignees</span><span class="err">:</span> <span class="pi">[</span><span class="nv">me</span><span class="pi">]</span>
              <span class="err">}</span><span class="s">);</span>

              <span class="s">// コメントで通知</span>
              <span class="s">await github.rest.issues.createComment({</span>
                <span class="s">owner</span><span class="err">:</span> <span class="s">context.repo.owner,</span>
                <span class="s">repo</span><span class="err">:</span> <span class="s">context.repo.repo,</span>
                <span class="s">issue_number</span><span class="err">:</span> <span class="s">issue.number,</span>
                <span class="s">body</span><span class="err">:</span> <span class="err">`</span><span class="s">🔧 No assignee was set, so I have assigned this to myself (@${me}).`</span>
              <span class="s">});</span>
            <span class="s">}</span>
</code></pre></div></div>

<p>今回は GitHub Script（JavaScript）でスクリプトを作成する方法を示します。コードの文法がより柔軟で書きやすくなります。</p>

<p>もちろん、もし前に言ったように各タスクを一つのファイルにしたい場合は、Job の If 条件を外して、直接 Action Workflow のトリガー条件を設定すれば良いです：</p>

<p><code class="language-plaintext highlighter-rouge">Automation-PullRequest-Auto-Assign.yml</code> <strong>：</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ワークフロー（アクション）名</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">Pull Request Automation - Auto Assignee Self</span>

<span class="c1"># トリガーイベント</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># PRイベント</span>
  <span class="na">pull_request</span><span class="pi">:</span>
    <span class="c1"># PRがオープンされたとき</span>
    <span class="na">types</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">opened</span><span class="pi">]</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">assign-self-if-no-assignee</span><span class="pi">:</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">担当者が指定されていない場合に自動で自分を割り当てる</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="c1"># 前述を参照、省略....</span>
</code></pre></div></div>

<p>Commit ファイルをリポジトリのメインブランチにプッシュした後、新しい PR を作成すると自動的に GitHub Actions がトリガーされます：</p>

<p><img src="/assets/404bd5c70040/1*Y-A6owUibNEFBoRFHnqIYg.webp" alt="" loading="lazy" decoding="async" width="1271" height="708" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjcxIiBoZWlnaHQ9IjcwOCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*Y-A6owUibNEFBoRFHnqIYg.png" /></p>

<p>現在、2つのジョブを実行します！</p>

<h4 id="実行結果-1">実行結果</h4>

<p><img src="/assets/404bd5c70040/1*23muCVgUJKmZt746khBMFQ.webp" alt="Demo PR" loading="lazy" decoding="async" width="1200" height="979" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk3OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*23muCVgUJKmZt746khBMFQ.png" /></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/pull/11" target="_blank">Demo PR</a></p>

<p>実行完了かつ成功後、PRにAssigneesがいない場合、自動的にPRの作成者をAssignし、コメントを投稿します。（すべて <code class="language-plaintext highlighter-rouge">github-actions</code> の権限で操作）</p>

<p><strong>完全なコード： <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/Automation-PullRequest.yml" target="_blank">Automation-PullRequest.yml</a></strong></p>

<h4 id="テスト再オープンreopened-pr">テスト再オープン(Reopened) PR</h4>

<p><img src="/assets/404bd5c70040/1*mcDa7TZjv6mO7HtwhOE-Vw.webp" alt="" loading="lazy" decoding="async" width="960" height="407" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjAiIGhlaWdodD0iNDA3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*mcDa7TZjv6mO7HtwhOE-Vw.png" /></p>

<p>Size Label Job のみが実行され、Auto Assignee Job はスキップされました。</p>

<blockquote>
  <p><em>このタスクもすでにActionとしてパッケージ化されており、そのまま再利用可能です。参考：<a href="https://github.com/pozil/auto-assign-issue" target="_blank">pozil/auto-assign-issue</a> 。</em></p>
</blockquote>

<h3 id="ケース--3">ケース — 3</h3>

<p>毎朝9時に現在のPR数と開いてからの経過時間を自動集計し、Slackの作業チームに通知メッセージを送信、さらに3ヶ月以上開いているPRを自動でクローズします。</p>

<h4 id="成果図-2">成果図</h4>

<p><img src="/assets/404bd5c70040/1*0stX9KpZi6PcXpG-90wyIg.webp" alt="" loading="lazy" decoding="async" width="508" height="147" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MDgiIGhlaWdodD0iMTQ3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*0stX9KpZi6PcXpG-90wyIg.png" /></p>

<p><img src="/assets/404bd5c70040/1*Nbg3r1zzhx24YIBEjPJnaw.webp" alt="" loading="lazy" decoding="async" width="928" height="187" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjgiIGhlaWdodD0iMTg3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*Nbg3r1zzhx24YIBEjPJnaw.png" /></p>

<ul>
  <li>
    <p>Slack ワークグループに毎朝自動でレポートを送信する</p>
  </li>
  <li>
    <p>90日を超えたPRを自動でクローズする</p>
  </li>
</ul>

<h4 id="動作の流れ-2">動作の流れ</h4>

<ul>
  <li>
    <p>GitHub Actions は毎朝9時に自動でトリガーされる</p>
  </li>
  <li>
    <p>GitHub Actions Workflow のトリガー</p>
  </li>
  <li>
    <p>github script で開いている PR の一覧を取得し、開いてからの日数を集計する方法</p>
  </li>
  <li>
    <p>Slack に統計レポートメッセージを送信する</p>
  </li>
  <li>
    <p>90日以上経過したPRをクローズする</p>
  </li>
  <li>
    <p>完了</p>
  </li>
</ul>

<h4 id="実践してみよう-2">実践してみよう</h4>

<p>Repo → Actions → New workflow → 自分でワークフローを設定する。</p>

<p><strong>ファイル名：</strong> <code class="language-plaintext highlighter-rouge">Automation-PullRequest-Daily.yml</code></p>

<h4 id="automation-pullrequest-dailyyml">Automation-PullRequest-Daily.yml</h4>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ワークフロー（Action）名</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">Pull Reqeust Automation - Daily Checker</span>

<span class="c1"># トリガーイベント</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># スケジュールによる定期実行</span>
  <span class="c1"># https://crontab.guru/</span>
  <span class="c1"># UTC時間</span>
  <span class="na">schedule</span><span class="pi">:</span>
    <span class="c1"># UTCの01:00 = 毎日UTC+8の09:00</span>
    <span class="pi">-</span> <span class="na">cron</span><span class="pi">:</span> <span class="s1">'</span><span class="s">0</span><span class="nv"> </span><span class="s">1</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">*'</span>
  <span class="c1"># 手動トリガー</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>

<span class="c1"># ジョブ</span>
<span class="c1"># ジョブは並行実行される</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="c1"># ジョブID</span>
  <span class="na">caculate-pr-status</span><span class="pi">:</span>
    <span class="c1"># ジョブ名（省略可、ログ表示で読みやすくなる）</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">Caculate PR Status</span>
    <span class="c1"># ランナーラベル - GitHubホステッドランナー ubuntu-latestで実行</span>
    <span class="c1"># プライベートリポジトリの場合は使用量が計算され、超過すると料金が発生する可能性あり</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>

    <span class="c1"># ジョブ出力</span>
    <span class="na">outputs</span><span class="pi">:</span>
      <span class="na">pr_list</span><span class="pi">:</span> <span class="s">${{ steps.pr-info.outputs.pr_list }}</span>

    <span class="c1"># ステップ</span>
    <span class="c1"># ステップは順番に実行される</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="c1"># ステップ名</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Fetch open PRs and caculate</span>
        <span class="c1"># ステップの外部からOutputを参照するために設定が必要</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">pr-info</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/github-script@v7</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">script</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">const now = new Date();</span>
            <span class="s">const per_page = 100;</span>
            <span class="s">let page = 1;</span>
            <span class="s">let allPRs = [];</span>
      
            <span class="s">while (true) {</span>
              <span class="s">const { data</span><span class="err">:</span> <span class="s">prs } = await github.rest.pulls.list({</span>
                <span class="s">owner</span><span class="err">:</span> <span class="s">context.repo.owner,</span>
                <span class="s">repo</span><span class="err">:</span> <span class="s">context.repo.repo,</span>
                <span class="s">state</span><span class="err">:</span> <span class="s1">'</span><span class="s">open'</span><span class="err">,</span>
                <span class="s">per_page,</span>
                <span class="s">page,</span>
              <span class="s">});</span>
              <span class="s">if (prs.length === 0) break;</span>
              <span class="s">allPRs = allPRs.concat(prs);</span>
              <span class="s">if (prs.length &lt; per_page) break;</span>
              <span class="s">page++;</span>
            <span class="s">}</span>
      
            <span class="s">const result = allPRs.map(pr =&gt; {</span>
              <span class="s">const created = new Date(pr.created_at);</span>
              <span class="s">const daysOpen = Math.floor((now - created) / (1000 * 60 * 60 * 24));</span>
              <span class="s">return {</span>
                <span class="s">pr</span><span class="err">:</span> <span class="s">pr.number.toString(),</span>
                <span class="s">title</span><span class="err">:</span> <span class="s">pr.title,</span>
                <span class="s">idle</span><span class="err">:</span> <span class="s">daysOpen</span>
              <span class="s">};</span>
            <span class="s">});</span>

            <span class="s">// Outputに設定、文字列のみ受け付ける</span>
            <span class="s">core.setOutput('pr_list', JSON.stringify(result));</span>
  <span class="c1"># ----</span>
  <span class="na">send-pr-summary-message-to-slack</span><span class="pi">:</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">Send PR Summary Messag to Slack</span>
    <span class="c1"># ジョブはデフォルトで並行実行、needsを使うと指定したジョブ完了まで待機する</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">caculate-pr-status</span><span class="pi">]</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Generate Message</span>
        <span class="c1"># ステップの外部からOutputを参照するために設定が必要</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">gen-msg</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/github-script@v7</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">script</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">const prList = JSON.parse(`${{ needs.caculate-pr-status.outputs.pr_list }}`);</span>
            <span class="s">const blocks = [];</span>
      
            <span class="s">// タイトル</span>
            <span class="s">blocks.push({</span>
              <span class="s">type</span><span class="err">:</span> <span class="s2">"</span><span class="s">section"</span><span class="err">,</span>
              <span class="na">text</span><span class="pi">:</span> <span class="pi">{</span>
                <span class="nv">type</span><span class="pi">:</span> <span class="s2">"</span><span class="s">mrkdwn"</span><span class="pi">,</span>
                <span class="nv">text</span><span class="pi">:</span> <span class="err">`</span><span class="nv">📬 *Open PR Report*\nTotal</span><span class="pi">:</span> <span class="err">*</span><span class="nv">$</span><span class="pi">{</span><span class="nv">prList.length</span><span class="pi">}</span><span class="err">*</span> <span class="nv">PR(s)`</span>
              <span class="pi">}</span>
          <span class="err">  }</span><span class="s">);</span>
      
            <span class="s">// 各PRを1行ずつ</span>
            <span class="s">for (const pr of prList) {</span>
              <span class="s">blocks.push({</span>
                <span class="s">type</span><span class="err">:</span> <span class="s2">"</span><span class="s">section"</span><span class="err">,</span>
                <span class="na">text</span><span class="pi">:</span> <span class="pi">{</span>
                  <span class="nv">type</span><span class="pi">:</span> <span class="s2">"</span><span class="s">mrkdwn"</span><span class="pi">,</span>
                  <span class="nv">text</span><span class="pi">:</span> <span class="err">`</span><span class="nv">• &lt;https</span><span class="pi">:</span><span class="nv">//github.com/$</span><span class="pi">{</span><span class="nv">context.repo.owner</span><span class="pi">}</span><span class="nv">/$</span><span class="pi">{</span><span class="nv">context.repo.repo</span><span class="pi">}</span><span class="nv">/pull/$</span><span class="pi">{</span><span class="nv">pr.pr</span><span class="pi">}</span><span class="nv">\\|PR</span> <span class="c1">#${pr.pr}&gt; *${pr.title}* - 🕒 ${pr.idle} day(s)`</span>
                <span class="pi">}</span>
          <span class="err">    }</span><span class="s">);</span>
            <span class="s">}</span>

            <span class="s">// Outputに設定、文字列のみ受け付ける</span>
            <span class="s">core.setOutput('blocks', JSON.stringify(blocks));</span>

            
      <span class="c1"># Slack公式のSlack API GitHub Actionsを使用</span>
      <span class="c1"># https://tools.slack.dev/slack-github-action/sending-techniques/sending-data-slack-api-method/</span>
      <span class="c1"># メッセージ送信</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Post text to a Slack channel</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">slackapi/slack-github-action@v2.1.0</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">method</span><span class="pi">:</span> <span class="s">chat.postMessage</span>
          <span class="na">token</span><span class="pi">:</span> <span class="s">${{ secrets.SLACK_BOT_TOKEN }}</span>
          <span class="na">payload</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">channel</span><span class="err">:</span> <span class="s">${{ vars.SLACK_TEAM_CHANNEL_ID }}</span>
            <span class="s">blocks</span><span class="err">:</span> <span class="s">${{ steps.gen-msg.outputs.blocks }}</span>
  <span class="c1"># ----</span>
  <span class="na">auto-close-old-prs</span><span class="pi">:</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">Auto Close Old PRs</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">caculate-pr-status</span><span class="pi">]</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Auto close PRs opened more than 90 days</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/github-script@v7</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">script</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">const prList = JSON.parse(`${{ needs.caculate-pr-status.outputs.pr_list }}`);</span>
            <span class="s">const oldPRs = prList.filter(pr =&gt; pr.idle &gt; 90);</span>

            <span class="s">for (const pr of oldPRs) {</span>
              <span class="s">await github.rest.pulls.update({</span>
                <span class="s">owner</span><span class="err">:</span> <span class="s">context.repo.owner,</span>
                <span class="s">repo</span><span class="err">:</span> <span class="s">context.repo.repo,</span>
                <span class="s">pull_number</span><span class="err">:</span> <span class="s">parseInt(pr.pr),</span>
                <span class="s">state</span><span class="err">:</span> <span class="s1">'</span><span class="s">closed'</span>
              <span class="err">}</span><span class="s">);</span>

              <span class="s">await github.rest.issues.createComment({</span>
                <span class="s">owner</span><span class="err">:</span> <span class="s">context.repo.owner,</span>
                <span class="s">repo</span><span class="err">:</span> <span class="s">context.repo.repo,</span>
                <span class="s">issue_number</span><span class="err">:</span> <span class="s">parseInt(pr.pr),</span>
                <span class="s">body</span><span class="err">:</span> <span class="err">`</span><span class="s">⚠️ This pull request has been automatically closed because it has been open for more than 90 days. Please reopen if needed.`</span>
              <span class="s">});</span>
            <span class="s">}</span>
            <span class="s">console.log(`Closed ${oldPRs.length} PR(s)`);</span>
</code></pre></div></div>

<p>この例では以下を使用します：</p>

<ul>
  <li>
    <p>on: schedule<br />
Crontab スケジュールによる自動トリガーと workflow_dispatch による手動トリガーのサポート</p>
  </li>
  <li>
    <p>Job output/Step output（どちらも文字列のみ）</p>
  </li>
  <li>
    <p>複数のジョブはデフォルトで並行実行されますが、<code class="language-plaintext highlighter-rouge">needs</code> を使って依存関係を設定し、順番待ちが可能です。</p>
  </li>
  <li>
    <p>Repo Secrets/Variables から設定を取得する</p>
  </li>
  <li>
    <p>Slack API の連携</p>
  </li>
</ul>

<p><strong>Repo Secrets — 新規追加</strong> <code class="language-plaintext highlighter-rouge">SLACK_BOT_TOKEN</code></p>

<p><img src="/assets/404bd5c70040/1*YC4DBHtKmX5XGgcSSzaE5A.webp" alt="" loading="lazy" decoding="async" width="1200" height="970" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk3MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*YC4DBHtKmX5XGgcSSzaE5A.png" /></p>

<ul>
  <li>Slack App の作成およびメッセージ送信権限の設定については、私の<a href="/posts/zrealm-ロボティックプロセスオートメーション/slackとchatgpt連携-openai-apiで自作slackアプリをpythonとgoogle-cloud-functionsで実装-bd94cc88f9c9/">以前の記事</a>を参照してください。</li>
</ul>

<p><strong>Repo Variables — 新規追加</strong> <code class="language-plaintext highlighter-rouge">SLACK_TEAM_CHANNEL_ID</code></p>

<p><img src="/assets/404bd5c70040/1*X4gZ5_IRvsiehAL0O9AleQ.webp" alt="" loading="lazy" decoding="async" width="1174" height="998" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTc0IiBoZWlnaHQ9Ijk5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*X4gZ5_IRvsiehAL0O9AleQ.png" /></p>

<p>Commit をファイルをリポジトリのメインブランチにプッシュした後、Actions に戻って手動でトリガーしてみましょう：</p>

<blockquote>
  <p><em>今後は毎日自動的にトリガーされます。</em></p>
</blockquote>

<p><img src="/assets/404bd5c70040/1*WNFKXl-QC2WGyaSWep5-DA.webp" alt="" loading="lazy" decoding="async" width="1048" height="438" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDQ4IiBoZWlnaHQ9IjQzOCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*WNFKXl-QC2WGyaSWep5-DA.png" /></p>

<p>Actions → プルリクエスト自動化 — デイリーチェッカー → ワークフローを実行 → ブランチ: main → ワークフローを実行。</p>

<p><strong>実行後にクリックして実行状況を確認できます：</strong></p>

<p><img src="/assets/404bd5c70040/1*4mvOxnd1uS4ZlxnNoNdHaQ.webp" alt="" loading="lazy" decoding="async" width="1087" height="545" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDg3IiBoZWlnaHQ9IjU0NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*4mvOxnd1uS4ZlxnNoNdHaQ.png" /></p>

<p><img src="/assets/404bd5c70040/1*BluzFgY2tM2E7DwoVq1jQw.webp" alt="" loading="lazy" decoding="async" width="1030" height="458" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDMwIiBoZWlnaHQ9IjQ1OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*BluzFgY2tM2E7DwoVq1jQw.png" /></p>

<p><code class="language-plaintext highlighter-rouge">needs</code> の制約があるため、ジョブの流れはまず <code class="language-plaintext highlighter-rouge">Calculate PR Status</code> が完了し、その後に <code class="language-plaintext highlighter-rouge">Auto Close Old PRs</code> と <code class="language-plaintext highlighter-rouge">Send PR Summary Message to Slack</code> が並行して実行されます。</p>

<h4 id="実行結果-2">実行結果</h4>

<p><strong>タスクがすべて成功した後に Slack メッセージを確認できます：</strong></p>

<p><img src="/assets/404bd5c70040/1*0stX9KpZi6PcXpG-90wyIg.webp" alt="" loading="lazy" decoding="async" width="508" height="147" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MDgiIGhlaWdodD0iMTQ3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*0stX9KpZi6PcXpG-90wyIg.png" /></p>

<p>成功 🚀🚀🚀</p>

<p><strong>完全なコード： <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/Automation-PullRequest-Daily.yml" target="_blank">Automation-PullRequest-Daily.yml</a></strong></p>

<h3 id="小結">小結</h3>

<blockquote>
  <p>上記の3つの事例が、GitHub Actions の基本的な理解に役立ち、自動化ワークフローのアイデアを刺激できれば幸いです。まずは <a href="https://docs.github.com/en/actions/reference/events-that-trigger-workflows" target="_blank">トリガーイベント</a> を必ず参照し、自分でワークフローを考案してスクリプトを作成してください。また、<a href="https://github.com/marketplace?type=actions" target="_blank"><strong>Marketplace</strong></a> で既存のアクションを探し、既存の資源を活用することも忘れないでください。</p>
</blockquote>

<p>本記事は入門基礎（コードのチェックアウトすら行いません）に過ぎません。次回の記事「<a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/"><strong>CI/CD 実践ガイド（三）：GitHub Actions を使ったアプリプロジェクトの CI と CD ワークフローの実装</strong></a>」では、より複雑で深い GitHub Actions Workflow を紹介します。</p>

<h4 id="github-自動化の拡張トピック">GitHub 自動化の拡張トピック</h4>

<p>GitHub は Slack と連携でき、リポジトリの PR 更新通知やデフォルトブランチへのプッシュ通知などを購読できます。</p>

<p><img src="/assets/404bd5c70040/1*BMTT4koRBIIsQ7_mklC86w.webp" alt="" loading="lazy" decoding="async" width="439" height="430" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MzkiIGhlaWdodD0iNDMwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*BMTT4koRBIIsQ7_mklC86w.png" /></p>

<p><strong>問題 1. GitHub メッセージで人をタグ付けできず、GitHub アカウントのみがタグ付けされ、Slack アカウントに通知が届かない：</strong></p>

<p><img src="/assets/404bd5c70040/1*Ddp0cEtXE10hScM1rozmtg.webp" alt="" loading="lazy" decoding="async" width="1300" height="946" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzAwIiBoZWlnaHQ9Ijk0NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*Ddp0cEtXE10hScM1rozmtg.png" /></p>

<p><img src="/assets/404bd5c70040/1*uHGJ7l__AdYoWT9KpvihLQ.webp" alt="" loading="lazy" decoding="async" width="1043" height="775" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDQzIiBoZWlnaHQ9Ijc3NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*uHGJ7l__AdYoWT9KpvihLQ.png" /></p>

<p><a href="https://slack.github.com/" target="_blank">Slack App</a> または Apps で GitHub を検索 → メッセージウィンドウを開く → <strong>Connect GitHub Account</strong> の手順を完了してください。これにより、GitHub が対応するあなたの Slack UID を認識し、メンションできるようになります。</p>

<p><strong>問題 2. プルリクエストリマインダー</strong></p>

<p>これはもともとサードパーティ製の機能だったのですが、後に直接 GitHub に統合されました。わざわざ自分で GitHub Actions を使ってスクリプトを書く必要はありません！</p>

<p><img src="/assets/404bd5c70040/1*BpMd2K0NBDE6xB1XzFY94Q.webp" alt="" loading="lazy" decoding="async" width="1084" height="1291" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDg0IiBoZWlnaHQ9IjEyOTEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/404bd5c70040/1*BpMd2K0NBDE6xB1XzFY94Q.png" /></p>

<blockquote>
  <p><a href="https://docs.github.com/en/organizations/organizing-members-into-teams/managing-scheduled-reminders-for-your-team" target="_blank"><strong><em>GitHub の組み込み機能はチーム単位の設定です。まず組織にチームを追加し、リポジトリをチームに割り当ててからプルリクエストリマインダーを設定する必要があります。</em></strong></a></p>
</blockquote>

<ul>
  <li>Slack チャンネルとルールを入力して保存すると、毎日自動でリマインドメッセージが送信され、Reviewer にタグ付けされます。設定方法は<a href="https://michaelheap.com/github-scheduled-reminders/" target="_blank">こちら</a>を参照してください。結果は以下の通りです：</li>
</ul>

<p><img src="/assets/404bd5c70040/1*kvqFXkIKIxP79Wm8vIaN0Q.webp" alt="&lt;https://michaelheap.com/github-scheduled-reminders/&gt;" loading="lazy" decoding="async" width="500" height="315" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MDAiIGhlaWdodD0iMzE1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*kvqFXkIKIxP79Wm8vIaN0Q.png" /></p>

<p><a href="https://michaelheap.com/github-scheduled-reminders/" target="_blank">https://michaelheap.com/github-scheduled-reminders/</a></p>

<p><strong>問題 4. GitHub PR メッセージ、作者が通知を受け取れない：</strong></p>

<p><img src="/assets/404bd5c70040/1*wmtXwXAcQZDXqInRd0ivPw.webp" alt="" loading="lazy" decoding="async" width="792" height="535" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3OTIiIGhlaWdodD0iNTM1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*wmtXwXAcQZDXqInRd0ivPw.png" /></p>

<blockquote>
  <p><em>これは長年の問題であり、PR の Slack メッセージで <strong>実は作者が誰かをスレッドで返信していることを知らない</strong> という点です。GitHub が送るこの Slack メッセージは Reviewers のみをタグ付けし、Assignee や PR 作者はタグ付けされません。</em></p>
</blockquote>

<p>この時、GitHub Actions を使った自動化ツールが役立ちます。PR Description の最後に作者を追記する Job を追加すれば、そのメッセージが Slack に送られる際にも作者がタグ付けされます：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Workflow(Action) 名称</span>
name: Pull Reqeust Automation
<span class="c"># 前述を参照、省略....</span>

  <span class="c"># ---------</span>
  append-author-to-pr-description:
    name: PR説明に作成者を追記
    <span class="c"># 共有トリガーイベントのため、Job内で判定し、Pull RequestがOpened（初回作成）の場合のみ実行。そうでなければスキップ</span>
    <span class="k">if</span>: github.event_name <span class="o">==</span> <span class="s1">'pull_request'</span> <span class="o">&amp;&amp;</span> github.event.action <span class="o">==</span> <span class="s1">'opened'</span>
    
    <span class="c"># このJobが失敗してもWorkflow全体には影響せず、他のJobを継続</span>
    <span class="k">continue</span><span class="nt">-on-error</span>: <span class="nb">true</span>
    
    <span class="c"># 最大タイムアウト時間を設定し、異常時の無限待機を防止</span>
    timeout-minutes: 10
    
    <span class="c"># Runnerラベル - GitHubホストランナー ubuntu-latest を使用して実行</span>
    <span class="c"># Privateリポジトリの場合は使用量が計算され、超過すると費用が発生する可能性あり</span>
    <span class="c"># ただしこのような小規模な自動化作業で過剰使用は稀</span>
    runs-on: ubuntu-latest
    steps:
      - name: PR説明に作成者を追記
        <span class="nb">env</span>:
          <span class="c"># secrets.GITHUB_TOKEN はGitHub Actions実行時に自動生成されるトークンで、Secretsに設定不要。GitHubリポジトリAPIの一部スコープ権限を持つ</span>
          <span class="c"># gh(GitHub) CLIはGH_TOKENをENVに注入する必要があり、ghに操作権限を付与</span>
          <span class="c"># https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows</span>
          GH_TOKEN: <span class="k">${</span><span class="p">{ secrets.GITHUB_TOKEN </span><span class="k">}</span><span class="o">}</span>

          <span class="c">#   ${{ github.xxx }} はGitHub ActionsのContext式</span>
          <span class="c">#   シェル変数ではなく、YAML解析時にGitHub Actionsが対応する値に置換</span>
          <span class="c">#   その他パラメータ：https://docs.github.com/en/actions/learn-github-actions/contexts#github-context</span>
          PR_NUMBER: <span class="k">${</span><span class="p">{ github.event.pull_request.number </span><span class="k">}</span><span class="o">}</span>
          AUTHOR_TAG: <span class="s1">'@${{ github.event.pull_request.user.login }}'</span>
        run: <span class="se">\\</span>|
          <span class="nv">PR_BODY</span><span class="o">=</span><span class="si">$(</span>gh <span class="nb">pr </span>view <span class="nv">$PR_NUMBER</span> <span class="nt">--repo</span> <span class="k">${</span><span class="p">{ github.repository </span><span class="k">}</span><span class="o">}</span> <span class="nt">--json</span> body <span class="nt">-q</span> <span class="s2">".body"</span><span class="si">)</span>
          <span class="nv">NEW_BODY</span><span class="o">=</span><span class="si">$(</span><span class="nb">printf</span> <span class="s2">"%s</span><span class="se">\n\n</span><span class="s2">Created by %s"</span> <span class="s2">"</span><span class="nv">$PR_BODY</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$AUTHOR_TAG</span><span class="s2">"</span><span class="si">)</span>
          gh <span class="nb">pr </span>edit <span class="nv">$PR_NUMBER</span> <span class="nt">--repo</span> <span class="k">${</span><span class="p">{ github.repository </span><span class="k">}</span><span class="o">}</span> <span class="nt">--body</span> <span class="s2">"</span><span class="nv">$NEW_BODY</span><span class="s2">"</span>
</code></pre></div></div>

<p><strong>完全なコード： <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/Automation-PullRequest.yml" target="_blank">Automation-PullRequest.yml</a></strong></p>

<p>PR を作成すると、自動的に説明の後に作成者情報が追加され、Slack メッセージにも正しく作成者がタグ付けされます：</p>

<p><img src="/assets/404bd5c70040/1*UtTDtIQJ0vJks79UzCQSAQ.webp" alt="" loading="lazy" decoding="async" width="953" height="370" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTMiIGhlaWdodD0iMzcwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*UtTDtIQJ0vJks79UzCQSAQ.png" /></p>

<p><img src="/assets/404bd5c70040/1*MjVsFqE--xAq1zSQfCNVdQ.webp" alt="" loading="lazy" decoding="async" width="416" height="244" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MTYiIGhlaWdodD0iMjQ0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*MjVsFqE--xAq1zSQfCNVdQ.png" /></p>

<p><strong>問題 5. GitHub が大量に通知メールを送ってきて非常に迷惑：</strong></p>

<p>GitHub リポジトリの通知と Slack の設定が完了したら、通知はすべて Slack に集約されます。GitHub の個人設定でメール通知をオフにしましょう：</p>

<p><img src="/assets/404bd5c70040/1*INgfO9B2bNFy-Nd1ZjnzOw.webp" alt="" loading="lazy" decoding="async" width="1200" height="630" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjYzMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*INgfO9B2bNFy-Nd1ZjnzOw.png" /></p>

<h4 id="その他">その他</h4>

<p>Actions は現在ディレクトリ構造を持っていませんが、Actions ページで最大5つの Actions をピン留めできます。また、Disable を使って特定の Action を一時停止することも可能です。</p>

<p><img src="/assets/404bd5c70040/1*ZD-5xkparhJqtnm2REeu6A.webp" alt="" loading="lazy" decoding="async" width="1238" height="599" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjM4IiBoZWlnaHQ9IjU5OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*ZD-5xkparhJqtnm2REeu6A.png" /></p>

<p>Insights で GitHub Actions の使用量と実行結果を確認できます：</p>

<p><img src="/assets/404bd5c70040/1*re91ZRtQ0frOF6GVJ-MKrw.webp" alt="" loading="lazy" decoding="async" width="1271" height="626" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjcxIiBoZWlnaHQ9IjYyNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*re91ZRtQ0frOF6GVJ-MKrw.png" /></p>

<h3 id="reuse-workflow-補足">Reuse Workflow 補足</h3>

<p><a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/">次の記事</a>では同じリポジトリ内でWorkflowを分割して再利用していますが、ここでは異なるリポジトリ間でWorkflowを分割して再利用する例を補足します。</p>

<p>先に Reuse Workflow を定義します: <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo-share-actions/blob/main/.github/workflows/Automation-label-pr-base-branch.yml" target="_blank"><strong>Automation-label-pr-base-branch.yml:</strong></a> <strong><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo-share-actions/blob/main/.github/workflows/Automation-label-pr-base-branch.yml" target="_blank">ZhgChgLi/github-actions-ci-cd-demo-share-actions</a> リポジトリ内</strong>。</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Automation-label-pr-base-branch</span>
<span class="na">run-name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">[Automation-label-pr-base-branch]</span><span class="nv"> </span><span class="s">${{</span><span class="nv"> </span><span class="s">github.event.inputs.PR_NUMBER</span><span class="nv"> </span><span class="se">\\</span><span class="s">|</span><span class="se">\\</span><span class="s">|</span><span class="nv"> </span><span class="s">github.ref</span><span class="nv"> </span><span class="s">}}"</span>

<span class="na">concurrency</span><span class="pi">:</span>
  <span class="na">group</span><span class="pi">:</span> <span class="s">${{ github.workflow }}-${{ github.event.inputs.PR_NUMBER \\|\\| github.ref }}</span>
  <span class="na">cancel-in-progress</span><span class="pi">:</span> <span class="kc">true</span>

<span class="c1"># トリガーイベント</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="c1"># 他のWorkflowからこのWorkflowを呼び出しトリガー</span>
  <span class="na">workflow_call</span><span class="pi">:</span>
    <span class="c1"># 入力データ</span>
    <span class="na">inputs</span><span class="pi">:</span>
      <span class="c1"># PR番号</span>
      <span class="na">PR_NUMBER</span><span class="pi">:</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">true</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
    <span class="c1"># シークレット入力</span>
    <span class="na">secrets</span><span class="pi">:</span>
      <span class="na">GH_TOKEN</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s2">"</span><span class="s">APIアクセス用のGitHubトークン"</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">true</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">label-pr-base-branch</span><span class="pi">:</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">PRのベースブランチにラベル付け</span>
    <span class="na">continue-on-error</span><span class="pi">:</span> <span class="kc">true</span>
    <span class="na">timeout-minutes</span><span class="pi">:</span> <span class="m">10</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">ベースブランチでPRにラベル付け</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">label-pr-base-branch</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">GH_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.GITHUB_TOKEN }}</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">PR_NUMBER="${{ inputs.PR_NUMBER }}"</span>
          <span class="s">REPO="${{ github.repository }}"</span>

          <span class="s">echo "📦 リポジトリ $REPO のPR</span> <span class="c1">#$PR_NUMBER を処理中"</span>

          <span class="c1"># PRのベースブランチを取得</span>
          <span class="s">BASE_BRANCH=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json baseRefName --jq '.baseRefName')</span>
          <span class="s">echo "🔖 PRのベースブランチ</span><span class="err">:</span> <span class="s">$BASE_BRANCH"</span>

          <span class="s"># 許可されたベースブランチのラベル</span>
          <span class="s">BRANCH_LABELS=("develop" "main" "master")</span>

          <span class="s"># ラベルが許可リストにあるか確認</span>
          <span class="s">if [[ " ${BRANCH_LABELS[@]} " =~ " ${BASE_BRANCH} " ]]; then</span>
            <span class="s">LABEL="$BASE_BRANCH"</span>
          <span class="s">else</span>
            <span class="s">echo "⚠️ ベースブランチ '$BASE_BRANCH' は許可リストにありません。ラベル付けをスキップします。"</span>
            <span class="s">exit </span><span class="m">0</span>
          <span class="s">fi</span>

          <span class="s"># 既存のベースブランチラベルを削除</span>
          <span class="s">EXISTING_LABELS=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json labels --jq '.labels[].name')</span>
          <span class="s">for EXISTING in $EXISTING_LABELS; do</span>
            <span class="s">if [[ " ${BRANCH_LABELS[@]} " =~ " ${EXISTING} " ]]; then</span>
              <span class="s">echo "🧹 既存のベースブランチラベルを削除中</span><span class="err">:</span> <span class="s">$EXISTING"</span>
              <span class="s">gh pr edit "$PR_NUMBER" --repo "$REPO" --remove-label "$EXISTING"</span>
            <span class="s">fi</span>
          <span class="s">done</span>

          <span class="s"># ラベルが存在しなければ作成</span>
          <span class="s">if ! gh label list --repo "$REPO" \\| grep -q "^$LABEL$"; then</span>
            <span class="s">echo "🆕 ラベルを新規作成</span><span class="err">:</span> <span class="s">$LABEL"</span>
            <span class="s">gh label create "$LABEL" --repo "$REPO" --description "PR targeting $LABEL branch" --color "ededed"</span>
          <span class="s">else</span>
            <span class="s">echo "✅ ラベル '$LABEL' は既に存在します"</span>
          <span class="s">fi</span>

          <span class="s"># ベースブランチラベルを追加</span>
          <span class="s">echo "🏷️ PR</span> <span class="c1">#$PR_NUMBER にラベル '$LABEL' を追加"</span>
          <span class="s">gh pr edit "$PR_NUMBER" --repo "$REPO" --add-label "$LABEL"</span>
</code></pre></div></div>

<p>元の <strong>メイン <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/Demo-Reuse-Action-From-Another-Repo.yml" target="_blank">ZhgChgLi/github-actions-ci-cd-demo</a> リポジトリに戻り、</strong> 新たにメインの <strong>Workflow <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/Demo-Reuse-Action-From-Another-Repo.yml" target="_blank">Demo-Reuse-Action-From-Another-Repo.yml</a> を追加します：</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Automation-label-pr-base-branch</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="na">pull_request</span><span class="pi">:</span>
    <span class="na">types</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">opened</span><span class="pi">]</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">call-label-pr-workflow</span><span class="pi">:</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">ベースブランチラベルワークフローを呼び出す</span>
    <span class="c1"># ✅ 呼び出されるワークフローが同じリポジトリ内の場合：</span>
    <span class="c1">#    uses: ./.github/workflows/Automation-label-pr-base-branch.yml</span>
    <span class="c1">#    注意：この書き方ではブランチを指定できません（呼び出し元ワークフローのブランチが固定で使用されます）</span>
    <span class="c1">#    参考例：</span>
    <span class="c1">#    - CD-Deploy-Form.yml が同リポジトリのワークフローを呼び出す</span>
    <span class="c1">#    - CD-Deploy.yml が別リポジトリのワークフローを呼び出す</span>
    <span class="c1">#</span>
    <span class="c1"># ✅ 呼び出されるワークフローが別リポジトリの場合：</span>
    <span class="c1">#    uses: {owner}/{repo}/.github/workflows/{file}.yml@{branch_or_tag}</span>
    <span class="c1">#    ブランチまたはタグを指定可能</span>
    <span class="c1">#    ref: https://github.com/ZhgChgLi/github-actions-ci-cd-demo-share-actions/blob/main/.github/workflows/Automation-label-pr-base-branch.yml</span>
    <span class="na">uses</span><span class="pi">:</span> <span class="s">ZhgChgLi/github-actions-ci-cd-demo-share-actions/.github/workflows/Automation-label-pr-base-branch.yml@main</span>
    <span class="na">with</span><span class="pi">:</span>
      <span class="na">PR_NUMBER</span><span class="pi">:</span> <span class="s">${{ github.event.number }}</span>
      
    <span class="c1"># すべての secrets を呼び出し元ワークフローから継承する場合は、直接 `inherit` を使う</span>
    <span class="c1"># secrets: inherit</span>
    <span class="c1">#</span>
    <span class="c1"># 特定の secrets のみ渡す場合は個別に指定</span>
    <span class="na">secrets</span><span class="pi">:</span>
      <span class="na">GH_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.GITHUB_TOKEN }}</span>
</code></pre></div></div>

<p>コミットしたファイルでPRを試してみてください。</p>

<p><strong>ワークフロー：メインリポジトリの <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/Demo-Reuse-Action-From-Another-Repo.yml" target="_blank">Demo-Reuse-Action-From-Another-Repo.yml</a> → 別のリポジトリの <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo-share-actions/blob/main/.github/workflows/Automation-label-pr-base-branch.yml" target="_blank">Automation-label-pr-base-branch.yml</a> を呼び出し、パラメータを渡してタスクを実行 → メインリポジトリに戻って結果を報告。</strong></p>

<p><img src="/assets/404bd5c70040/1*13bqlAgpBkHM7UthTJAuOg.webp" alt="" loading="lazy" decoding="async" width="1119" height="453" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTE5IiBoZWlnaHQ9IjQ1MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*13bqlAgpBkHM7UthTJAuOg.png" /></p>

<p><img src="/assets/404bd5c70040/1*CAF3HzS4PHBveDQYu3H73g.webp" alt="" loading="lazy" decoding="async" width="402" height="145" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MDIiIGhlaWdodD0iMTQ1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*CAF3HzS4PHBveDQYu3H73g.png" /></p>

<p>成功！</p>

<h4 id="private-repo-アクセス問題">Private Repo アクセス問題</h4>

<p>ここで注意すべきセキュリティの問題があります。Publicリポジトリなら全く問題ありませんが、Privateリポジトリ内でReuse Workflowを使う場合は、<strong>同じ組織内の他のリポジトリであること + そのリポジトリもPrivateであること + 設定で許可されていること</strong>が揃って初めてPrivateリポジトリのReuse Workflowにアクセスして使用できます。</p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Public — ZhgChgLi/ReuseRepo</code> + <code class="language-plaintext highlighter-rouge">Private or Public-ZhgChgli or harry/myRepo</code> = ✅</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Private — ZhgChgLi/ReuseRepo</code> + <code class="language-plaintext highlighter-rouge">Private or Public— harry/myRepo</code> = ❌</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Private — ZhgChgLi/ReuseRepo</code> + <code class="language-plaintext highlighter-rouge">Public — ZhgChgLi/anotherRepo</code> = ❌</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Private — ZhgChgLi/ReuseRepo</code> + <code class="language-plaintext highlighter-rouge">Private — ZhgChgLi/anotherRepo</code> = ✅</p>
  </li>
</ul>

<p><strong>許可されている方法の設定は、Reuse Workflow Repo → Settings → Actions → General → Access で行います：</strong></p>

<p><img src="/assets/404bd5c70040/1*iZCEifgyArTJS3URMSk01g.webp" alt="" loading="lazy" decoding="async" width="725" height="300" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MjUiIGhlaWdodD0iMzAwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*iZCEifgyArTJS3URMSk01g.png" /></p>

<p>チェックを変更：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>'ZhgChgLi' 組織内のリポジトリからアクセス可能
'ZhgChgLi' 組織に属する他のリポジトリのワークフローは、このリポジトリ内のアクションや再利用可能なワークフローにアクセスできます。アクセスはプライベートリポジトリからのみ許可されます。
</code></pre></div></div>

<p>「保存」をクリックして、完了です。</p>

<p><strong>権限がない場合、以下のエラーメッセージが表示されます：</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>無効なワークフローファイル: .github/workflows/Demo-reuse-action-from-another-repo.yml#L21
呼び出されたワークフローの解析エラー
<span class="s2">".github/workflows/Demo-reuse-action-from-another-repo.yml"</span>
-&gt; <span class="s2">"ZhgChgLi/github-actions-ci-cd-demo-share-actions/.github/workflows/Automation-label-pr-base-branch.yml@main"</span>
: ワークフローが見つかりません。
</code></pre></div></div>

<h3 id="github-actions-script-文法補足">GitHub Actions Script 文法補足</h3>

<p>補足として、皆さんが疑問に感じるかもしれない <code class="language-plaintext highlighter-rouge">${{ XXX }}</code> や <code class="language-plaintext highlighter-rouge">${XXX}</code>、<code class="language-plaintext highlighter-rouge">$XXX</code> の変数構文について。</p>

<p><strong>Demo-Env-Vars-.yml:</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Demo-Env-Vars</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">print-env-vars</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">print-env</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">env</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">context-vars-vs-vars</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">SAY_MY_NAME</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Heisenberg"</span>
          <span class="c1"># GitHub Actions Context 式、下記説明と同じ</span>
          <span class="na">FROM_REF</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">github.ref</span><span class="nv"> </span><span class="s">}}"</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s"># シェルスクリプト：</span>
          <span class="s"># カスタム注入された ENV 変数の参照</span>
          <span class="s"># ${SAY_MY_NAME} または $SAY_MY_NAME どちらも可</span>
          <span class="s"># ${XX} は文字列結合時に便利：</span>
          <span class="s">echo "HI</span><span class="err">:</span> <span class="s">${SAY_MY_NAME}"</span>
          
          <span class="s"># 💡 GitHub Actions Context 式</span>
          <span class="s"># これはシェル変数ではなく、YAML解析時に GitHub Actions が対応する値に置換</span>
          <span class="s"># ⚠ ローカルや GitHub Actions 以外の環境では失敗する</span>
          <span class="s"># 🔗 https://docs.github.com/en/actions/learn-github-actions/contexts#github-context</span>
          <span class="s">BRANCH_NAME_FROM_CONTEXT="${{ github.ref }}"</span>
          
          <span class="s"># 💡 GitHub Actions 実行時の環境変数</span>
          <span class="s"># これらは runner がシェル実行時に GitHub Actions から自動注入される</span>
          <span class="s"># ✅ 他環境では export や ENV で同じ変数を事前定義すれば利用可</span>
          <span class="s"># 🔗 https://docs.github.com/en/actions/learn-github-actions/environment-variables</span>
          <span class="s">BRANCH_NAME_FROM_ENV_VARS="${GITHUB_REF}"</span>
          
          <span class="s">echo "FROM_REF</span><span class="err">:</span> <span class="s">${FROM_REF}"</span>
          <span class="s">echo "BRANCH_NAME_FROM_CONTEXT</span><span class="err">:</span> <span class="s">${BRANCH_NAME_FROM_CONTEXT}"</span>
          <span class="s">echo "BRANCH_NAME_FROM_ENV_VARS</span><span class="err">:</span> <span class="s">${BRANCH_NAME_FROM_ENV_VARS}"</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">print-github-script-env</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/github-script@v7</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">SAY_MY_NAME</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Heisenberg"</span>
          <span class="c1"># GitHub Actions Context 式、上記説明と同じ</span>
          <span class="na">FROM_REF</span><span class="pi">:</span> <span class="s2">"</span><span class="s">${{</span><span class="nv"> </span><span class="s">github.ref</span><span class="nv"> </span><span class="s">}}"</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">script</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">// GitHub Script</span><span class="na">: (JavaScript (Node.js))</span><span class="pi">:</span>
            <span class="s">// process.env から ENV 値を取得</span>
            <span class="s">console.log(`HI</span><span class="err">:</span> <span class="s">${process.env.SAY_MY_NAME}`);</span>
            <span class="s">console.log(`FROM_REF</span><span class="err">:</span> <span class="s">${process.env.FROM_REF}`);</span>
            <span class="s">// github-script では context 変数に自動注入されて JS から直接参照可能</span>
            <span class="s">// https://docs.github.com/en/actions/learn-github-actions/contexts#github-context</span>
            <span class="s">const branch_name_from_context_vars = context.ref;</span>
            <span class="s">console.log(`branch_name_from_context_vars</span><span class="err">:</span> <span class="s">${branch_name_from_context_vars}`);</span>
            <span class="s">// 同様に GitHub Actions Context 式も使用可（意味はあまりない）</span><span class="err">:</span>
            <span class="s">const branch_name_from_context = "${{ github.ref }}";</span>
            <span class="s">console.log(`branch_name_from_context</span><span class="err">:</span> <span class="s">${branch_name_from_context}`);</span>
            
            <span class="s">for (const [key, value] of Object.entries(process.env)) {</span>
              <span class="s">console.log(`${key}=${value}`);</span>
            <span class="s">}</span>
            <span class="s">// github-script 内の github オブジェクトは Octokit REST API のインスタンス</span>
            <span class="s">// GitHub API 操作用</span>
            <span class="s">// 例：</span>
            <span class="s">// await github.rest.pulls.list({</span>
            <span class="s">//   owner</span><span class="err">:</span> <span class="s">context.repo.owner,</span>
            <span class="s">//   repo</span><span class="err">:</span> <span class="s">context.repo.repo,</span>
            <span class="s">//   state</span><span class="err">:</span> <span class="s2">"</span><span class="s">open"</span>
            <span class="s">//  });</span>
      <span class="c1"># gh CLI はデフォルトで GITHUB_TOKEN を使用しない；GH_TOKEN が必要</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">gh CLI without GH_TOKEN (expected to fail)</span>
        <span class="na">continue-on-error</span><span class="pi">:</span> <span class="kc">true</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">PR_COUNT=$(gh pr list --repo $GITHUB_REPOSITORY --json number --jq 'length')</span>
          <span class="s">echo "Found $PR_COUNT open pull requests"</span>
      
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">gh CLI with GH_TOKEN (expected to succeed)</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="c1"># GH_TOKEN を割り当てて gh CLI の認証を可能にする</span>
          <span class="c1"># https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows</span>
          <span class="na">GH_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.GITHUB_TOKEN }}</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">PR_COUNT=$(gh pr list --repo $GITHUB_REPOSITORY --json number --jq 'length')</span>
          <span class="s">echo "Found $PR_COUNT open pull requests"</span>
      
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">github-script auto-authentication (no GH_TOKEN needed)</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/github-script@v7</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">script</span><span class="pi">:</span> <span class="s">\\|</span>
            <span class="s">// github = Octokit REST クライアント（GITHUB_TOKEN で自動認証済み）</span>
            <span class="s">const pulls = await github.rest.pulls.list({</span>
              <span class="s">owner</span><span class="err">:</span> <span class="s">context.repo.owner,</span>
              <span class="s">repo</span><span class="err">:</span> <span class="s">context.repo.repo,</span>
              <span class="s">state</span><span class="err">:</span> <span class="s2">"</span><span class="s">open"</span>
            <span class="err">}</span><span class="s">);</span>
            <span class="s">console.log(`Found ${pulls.data.length} open pull requests`);</span>
</code></pre></div></div>

<h4 id="-xxx--github-actions-コンテキスト式">${{ XXX }} GitHub Actions コンテキスト式</h4>

<p><img src="/assets/404bd5c70040/1*e3jpPuwdmf005cjbaXjAwQ.webp" alt="" loading="lazy" decoding="async" width="789" height="684" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3ODkiIGhlaWdodD0iNjg0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*e3jpPuwdmf005cjbaXjAwQ.png" /></p>

<p><img src="/assets/404bd5c70040/1*ed5Wm7Xk48xuP8yQzHpJ9w.webp" alt="" loading="lazy" decoding="async" width="880" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4ODAiIGhlaWdodD0iODAwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*ed5Wm7Xk48xuP8yQzHpJ9w.png" /></p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">${{ XXX }}</code> は GitHub Actions のコンテキスト式で、<strong>YAML の解析時に GitHub Actions によって対応する値に置き換えられます</strong>（上図の <code class="language-plaintext highlighter-rouge">BRANCH_NAME_FROM_CONTEXT</code> のように）</p>
  </li>
  <li>
    <p>利用可能な式の全リストは<a href="https://docs.github.com/en/actions/learn-github-actions/contexts#github-context" target="_blank">公式ドキュメント</a>を参照してください。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">${XXX}</code> や <code class="language-plaintext highlighter-rouge">$XXX</code> は実際の環境変数で、<code class="language-plaintext highlighter-rouge">${XXX}</code> は文字列連結時に便利です。</p>
  </li>
  <li>
    <p>GitHub Actions はデフォルトでいくつかの環境変数を注入します。詳細は<a href="https://docs.github.com/en/actions/learn-github-actions/environment-variables" target="_blank">公式ドキュメント</a>をご覧ください。</p>
  </li>
</ul>

<h4 id="actionsgithub-scriptv7">actions/github-script@v7</h4>

<p><img src="/assets/404bd5c70040/1*TjJQnlAAU3VRwS9_dFz1yA.webp" alt="" loading="lazy" decoding="async" width="718" height="913" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MTgiIGhlaWdodD0iOTEzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*TjJQnlAAU3VRwS9_dFz1yA.png" /></p>

<p><img src="/assets/404bd5c70040/1*5bHEdjrGsVdWnYSQgpnsZA.webp" alt="" loading="lazy" decoding="async" width="1018" height="1150" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDE4IiBoZWlnaHQ9IjExNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/404bd5c70040/1*5bHEdjrGsVdWnYSQgpnsZA.png" /></p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">github-script</code> でも <code class="language-plaintext highlighter-rouge">${{ XXX }}</code> は GitHub Actions のコンテキスト式として使えますが、あまり意味はありません。なぜなら <strong>github-script 環境ではデフォルトで context 変数が注入されており、JavaScript 内で直接参照できるからです</strong>。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">github-script</code> では、<code class="language-plaintext highlighter-rouge">github</code> オブジェクトは Octokit REST API のインスタンスです。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">github-script</code> は <code class="language-plaintext highlighter-rouge">env:</code> から変数を注入できますが、<code class="language-plaintext highlighter-rouge">${process.env.xxx}</code> を使ってアクセスする必要があります。</p>
  </li>
  <li>
    <p>同様にいくつかの環境変数がデフォルトで注入されます。詳細は<a href="https://docs.github.com/en/actions/learn-github-actions/environment-variables" target="_blank">公式ドキュメント</a>を参照してください。<code class="language-plaintext highlighter-rouge">${process.env.xxx}</code>でアクセス可能ですが、すでに <code class="language-plaintext highlighter-rouge">context</code> 変数があるため、ここからアクセスする意味はあまりありません。</p>
  </li>
</ul>

<p><img src="/assets/404bd5c70040/1*oW85Sju0sN4caXiaLSg32A.webp" alt="" loading="lazy" decoding="async" width="735" height="408" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MzUiIGhlaWdodD0iNDA4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*oW85Sju0sN4caXiaLSg32A.png" /></p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">github-script</code> は自動的に <code class="language-plaintext highlighter-rouge">github-token</code> を渡すため、指定する必要はありません。</li>
</ul>

<h4 id="gh-cli-gh_token">gh cli GH_TOKEN</h4>

<p><img src="/assets/404bd5c70040/1*NUfaaKIobZWVBuXrGg0TPw.webp" alt="" loading="lazy" decoding="async" width="866" height="431" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjYiIGhlaWdodD0iNDMxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*NUfaaKIobZWVBuXrGg0TPw.png" /></p>

<ul>
  <li>
    <p>GitHub Actions の Shell Script で <code class="language-plaintext highlighter-rouge">gh cli</code> を使用する場合、<code class="language-plaintext highlighter-rouge">GH_TOKEN</code> パラメータを指定する必要があります</p>
  </li>
  <li>
    <p>デフォルトのトークン — <code class="language-plaintext highlighter-rouge">secrets.GITHUB_TOKEN</code> を直接使用可能（GitHub Actions 実行時に自動生成）</p>
  </li>
  <li>
    <p><strong>デフォルトのトークンには基本的な権限がありますが、操作するコマンドの権限が不足している場合は <a href="https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows" target="_blank">Personal Access Token</a> を使用してください。チームでの利用は共有アカウントでPATを作成することを推奨します。</strong></p>
  </li>
</ul>

<p><strong>完全なコード： <a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/blob/main/.github/workflows/Demo-Env-Vars-.yml" target="_blank">Demo-Env-Vars-.yml</a></strong></p>

<p>GitHub Actions はすでに開発が完了しているので、次のステップとして GitHub Hosted Runner を自分の Self-hosted Runner に置き換えることができます。</p>

<blockquote>
  <p><em>GitHub Hosted Runner には月間2,000分の無料枠があります。小さな自動化タスクならそれほど時間がかからず、Linuxマシン上で動作するためコストも低く、無料枠を使い切らないことも多いです。<strong>必ずしも Self-hosted Runner に変更する必要はありません</strong>。Runner を変更する場合は環境を正しく整える必要があります（例えば、GitHub Hosted Runner には gh cli が標準搭載されていますが、Self-hosted Runner では自分でインストールする必要があります）。<strong>この記事ではあくまで教育目的で切り替えを行っています</strong>。</em></p>
</blockquote>

<blockquote>
  <p><em>CI/CD タスクを実行する場合にのみ、Self-hosted Runner を使用する必要があります。</em></p>
</blockquote>

<h4 id="self-hosted-runner-の追加">Self-hosted Runner の追加</h4>

<blockquote>
  <p><em>本文は <strong>macOS M1</strong> を例にしています。</em></p>
</blockquote>

<p><img src="/assets/404bd5c70040/1*mEInaj-tLaprMAa2OfowCw.webp" alt="" loading="lazy" decoding="async" width="1225" height="1136" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjI1IiBoZWlnaHQ9IjExMzYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/404bd5c70040/1*mEInaj-tLaprMAa2OfowCw.png" /></p>

<ul>
  <li>
    <p>設定 → Actions → Runners → 新しいセルフホストランナー。</p>
  </li>
  <li>
    <p><strong>Runner image:</strong> macOS</p>
  </li>
  <li>
    <p><strong>Architecture</strong> : M1 は ARM64 を選択すると実行が速くなります</p>
  </li>
</ul>

<p><strong>実機のコンピュータでターミナルを開く。</strong></p>

<p><strong>Download 手順に従ってローカルPCで完了させる：</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 任意のパスに Runner ディレクトリを作成</span>
<span class="nb">mkdir </span>actions-runner <span class="o">&amp;&amp;</span> <span class="nb">cd </span>actions-runner
<span class="c"># Runner イメージをダウンロード</span>
curl <span class="nt">-o</span> actions-runner-osx-x64-2.325.0.tar.gz <span class="nt">-L</span> https://github.com/actions/runner/releases/download/v2.325.0/actions-runner-osx-x64-2.325.0.tar.gz

<span class="c"># 任意: ハッシュの検証</span>
<span class="nb">echo</span> <span class="s2">"0562bd934b27ca0c6d8a357df00809fbc7b4d5524d4aeb6ec152e14fd520a4c3  actions-runner-osx-x64-2.325.0.tar.gz"</span> <span class="se">\\</span>| shasum <span class="nt">-a</span> 256 <span class="nt">-c</span>

<span class="c"># 解凍</span>
<span class="nb">tar </span>xzf ./actions-runner-osx-x64-2.325.0.tar.gz
</code></pre></div></div>

<blockquote>
  <p><em>以上はあくまで参考です；最新の Runner イメージを使用するには、設定ページの手順に従うことをお勧めします。</em></p>
</blockquote>

<p><img src="/assets/404bd5c70040/1*Q0k0EPjrY2V4owseESe5lg.webp" alt="" loading="lazy" decoding="async" width="1161" height="197" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTYxIiBoZWlnaHQ9IjE5NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*Q0k0EPjrY2V4owseESe5lg.png" /></p>

<p><strong>設定 Configure:</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 設定ページのコマンドを参照してください。Tokenは時間とともに変わります</span>
./config.sh <span class="nt">--url</span> https://github.com/ORG/REPO <span class="nt">--token</span> XXX
</code></pre></div></div>

<p>順番に入力してください：</p>

<ul>
  <li>
    <p>ランナーを追加するランナーグループの名前を入力してください：[EnterキーでDefault] <strong>そのままEnterを押す</strong><br />
*ランナーグループの機能は、Organizationレベルで登録されたランナーのみ利用可能です</p>
  </li>
  <li>
    <p>Enter the name of runner: [press Enter for ZhgChgLideMacBook-Pro] <strong>設定したいランナー名を入力してください。例：</strong> <code class="language-plaintext highlighter-rouge">app-runner-1</code> <strong>またはそのまま Enter を押してください</strong></p>
  </li>
  <li>
    <p>This runner will have the following labels: ‘self-hosted’, ‘macOS’, ‘X64’<br />
Enter any additional labels (ex. label-1,label-2): [press Enter to skip]<br />
<strong>設定したい Runner のラベルを入力してください。複数のカスタムラベルを入力して後で使いやすくできます</strong><br />
前述の通り、GitHub Actions/Runner は対応するラベルに基づいてジョブを取得します。<strong>デフォルトのラベルだけを使うと、組織内の他の Runner がジョブを実行する場合があるため、カスタムラベルを設定するのが安全です</strong>。<br />
ここでは自分で適当に <code class="language-plaintext highlighter-rouge">self-hosted-zhgchgli</code> というラベルを設定しました。</p>
  </li>
  <li>
    <p>作業フォルダ名を入力してください: [Enterで_work] <strong>そのままEnterを押す</strong></p>
  </li>
</ul>

<p>√ Settings Saved. が表示されたら、設定が完了したことを意味します。</p>

<p><img src="/assets/404bd5c70040/1*yxLfii0rWhzsiFuYVmPgFw.webp" alt="" loading="lazy" decoding="async" width="929" height="501" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjkiIGhlaWdodD0iNTAxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*yxLfii0rWhzsiFuYVmPgFw.png" /></p>

<p><strong>Runnerの起動:</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./run.sh
</code></pre></div></div>

<p>出現 √ Connected to GitHub、Listening for Jobs と表示されていれば、すでに Actions のジョブを監視しています：</p>

<p><img src="/assets/404bd5c70040/1*1RmPPOosAoCxHA9tg_WE2w.webp" alt="" loading="lazy" decoding="async" width="290" height="98" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOTAiIGhlaWdodD0iOTgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/404bd5c70040/1*1RmPPOosAoCxHA9tg_WE2w.png" /></p>

<blockquote>
  <p><strong><em>このターミナルウィンドウを閉じない限り、タスクの受信を続けます。</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>🚀🚀🚀同じパソコンで複数のターミナルを開き、異なるディレクトリで複数のランナーを起動できます。</em></strong></p>
</blockquote>

<p><strong>リポジトリ設定ページに戻ると、Runnerがタスクを待機しているのが確認できます：</strong></p>

<p><img src="/assets/404bd5c70040/1*jjq5NTPYMuC3gH3ey_VTtg.webp" alt="" loading="lazy" decoding="async" width="802" height="247" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MDIiIGhlaWdodD0iMjQ3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*jjq5NTPYMuC3gH3ey_VTtg.png" /></p>

<p><strong>ステータス：</strong></p>

<ul>
  <li>
    <p>Idle: アイドル状態、タスク待機中</p>
  </li>
  <li>
    <p>Active: タスク実行中</p>
  </li>
  <li>
    <p>Offline: ランナーがオフラインです</p>
  </li>
</ul>

<h4 id="workflowgithub-actions-runner-を-self-hosted-runner-に変更する">Workflow(GitHub Actions) Runner を Self-hosted Runner に変更する</h4>

<p><code class="language-plaintext highlighter-rouge">Automation-PullRequest.yml</code> を例にすると：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># 前述を参照してください、省略....</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">label-pr-by-file-count</span><span class="pi">:</span>
    <span class="c1"># 前述を参照してください、省略....</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">self-hosted-zhgchgli</span><span class="pi">]</span>
    <span class="c1"># 前述を参照してください、省略....</span>
  <span class="c1"># ---------</span>
  <span class="na">assign-self-if-no-assignee</span><span class="pi">:</span>
    <span class="c1"># 前述を参照してください、省略....</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">self-hosted-zhgchgli</span><span class="pi">]</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="c1"># 前述を参照してください、省略....</span>
</code></pre></div></div>

<p>Commit ファイルをリポジトリのメインブランチにプッシュした後、PR を再度作成して Actions をトリガーし、検証します。</p>

<p><strong>Runner のターミナルに戻ると、新しいジョブが来ているのが確認でき、実行中および実行結果が表示されます：</strong></p>

<p><img src="/assets/404bd5c70040/1*Hu0DxKQbenPmBEw8swv65A.webp" alt="" loading="lazy" decoding="async" width="628" height="100" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MjgiIGhlaWdodD0iMTAwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*Hu0DxKQbenPmBEw8swv65A.png" /></p>

<p>失敗しました。なぜなら、私のローカルPCに <a href="https://github.com/cli/cli" target="_blank">gh cli</a> 環境がインストールされていないからです：</p>

<p><img src="/assets/404bd5c70040/1*9xguacdPATIeEZdbFszmHw.webp" alt="" loading="lazy" decoding="async" width="973" height="123" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NzMiIGhlaWdodD0iMTIzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*9xguacdPATIeEZdbFszmHw.png" /></p>

<p><code class="language-plaintext highlighter-rouge">brew install gh</code> を使って実機に gh をインストールした後、再度実行をトリガーする：</p>

<p><img src="/assets/404bd5c70040/1*TbkAt00K89Ysbix33dK8ZA.webp" alt="" loading="lazy" decoding="async" width="631" height="29" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MzEiIGhlaWdodD0iMjkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/404bd5c70040/1*TbkAt00K89Ysbix33dK8ZA.png" /></p>

<p>成功しました！これでこのジョブは完全に自分たちのコンピュータ上で実行され、GitHub Hosted Runner は使わず、料金も発生しません。</p>

<p><strong>Action Log でジョブが実行された Runner やマシンを確認できます：</strong></p>

<p><img src="/assets/404bd5c70040/1*oqLcWfn6cbWsCt9fVsrikQ.webp" alt="" loading="lazy" decoding="async" width="1092" height="826" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDkyIiBoZWlnaHQ9IjgyNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/404bd5c70040/1*oqLcWfn6cbWsCt9fVsrikQ.png" /></p>

<h4 id="runs-on--runner-label-設定">runs-on: [ <strong>Runner Label] 設定</strong></h4>

<p>ここは AND です。GitHub Runner は現時点で OR による Runner 選択をサポートしていません。</p>

<p>例えば、<code class="language-plaintext highlighter-rouge">[self-hosted, macOS, app]</code> → Runner が <strong>同時に</strong> <code class="language-plaintext highlighter-rouge">self-hosted, macOS, app</code> の3つのラベルを持っている場合にのみ、ジョブを受け取って実行します。</p>

<p>もし一つの Job で異なる Runner 環境の結果を同時にテストしたい場合は、<code class="language-plaintext highlighter-rouge">matrix</code> パラメータを使用できます：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">jobs</span><span class="pi">:</span>
  <span class="na">test</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">${{ matrix.runner }}</span>
    <span class="na">strategy</span><span class="pi">:</span>
      <span class="na">matrix</span><span class="pi">:</span>
        <span class="na">runner</span><span class="pi">:</span>
          <span class="pi">-</span> <span class="pi">[</span><span class="nv">self-hosted</span><span class="pi">,</span> <span class="nv">linux</span><span class="pi">,</span> <span class="nv">high-memory</span><span class="pi">]</span>
          <span class="pi">-</span> <span class="pi">[</span><span class="nv">self-hosted</span><span class="pi">,</span> <span class="nv">macos</span><span class="pi">,</span> <span class="nv">xcode-15</span><span class="pi">]</span>

    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">run</span><span class="pi">:</span> <span class="s">echo "Running on ${{ matrix.runner }}"</span>
</code></pre></div></div>

<p>こうすると、このジョブは以下の2つの Runner Labels の Runner 上で並行してそれぞれ1回ずつ実行されます：</p>

<ul>
  <li>
    <p>self-hosted、linux、高メモリ</p>
  </li>
  <li>
    <p>self-hosted、macos、xcode-15</p>
  </li>
</ul>

<blockquote>
  <p><strong><em>Runner はまだサポートしていません：</em></strong></p>
</blockquote>

<blockquote>
  <p><em>- または Runner の選択</em></p>
</blockquote>

<blockquote>
  <p><em>- Runner の重み付け設定</em></p>
</blockquote>

<h4 id="runner-をサービスとして登録する">Runner をサービスとして登録する</h4>

<p>公式ドキュメント「 <a href="https://docs.github.com/en/actions/how-tos/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service?platform=mac" target="_blank">Configuring the self-hosted runner application as a service</a> 」を参照して、Runner を直接システムサービスとして登録できます。これにより、バックグラウンドで実行され（Terminal を開かずに前景での操作不要）、起動時に自動的に開始されます。</p>

<p>複数の Runner がある場合は、「 <a href="https://docs.github.com/en/actions/how-tos/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service?platform=mac#customizing-the-self-hosted-runner-service-1" target="_blank">Customizing the self-hosted runner service</a> 」の設定で異なる名前を登録するようにしてください。</p>

<blockquote>
  <p><em>iOSで現在調査中の問題があります。<strong>バックグラウンドサービスに変更してからアーカイブ時にエラーが発生しており（キーチェーンの権限が関係している疑いがあります）</strong>、当時は時間がなく、先にフォアグラウンドのターミナルランナーを使用しました。</em></p>
</blockquote>

<p>もし従来のフォアグラウンドアプリを起動時に自動起動させたい場合は、<code class="language-plaintext highlighter-rouge">~/Library/LaunchAgents</code> に自動起動設定ファイルを追加する必要があります：</p>

<p><code class="language-plaintext highlighter-rouge">actions.runner.REPO.RUNNER_NAME.plist</code> ：</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="cp">&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;</span>
<span class="nt">&lt;plist</span> <span class="na">version=</span><span class="s">"1.0"</span><span class="nt">&gt;</span>
 <span class="nt">&lt;dict&gt;</span>
  <span class="nt">&lt;key&gt;</span>Label<span class="nt">&lt;/key&gt;</span>
  <span class="nt">&lt;string&gt;</span>actions.runner.REPO.RUNNER_NAME<span class="nt">&lt;/string&gt;</span>
  <span class="c">&lt;!-- Terminal.app を指定して起動 --&gt;</span>
  <span class="nt">&lt;key&gt;</span>ProgramArguments<span class="nt">&lt;/key&gt;</span>
  <span class="nt">&lt;array&gt;</span>
   <span class="nt">&lt;string&gt;</span>/usr/bin/open<span class="nt">&lt;/string&gt;</span>
   <span class="nt">&lt;string&gt;</span>-a<span class="nt">&lt;/string&gt;</span>
   <span class="nt">&lt;string&gt;</span>Terminal<span class="nt">&lt;/string&gt;</span>
   <span class="nt">&lt;string&gt;</span>/Users/zhgchgli/Documents/actions-runner/run.sh<span class="nt">&lt;/string&gt;</span>
  <span class="nt">&lt;/array&gt;</span>
  <span class="nt">&lt;key&gt;</span>RunAtLoad<span class="nt">&lt;/key&gt;</span>
  <span class="nt">&lt;true/&gt;</span>
  <span class="nt">&lt;key&gt;</span>WorkingDirectory<span class="nt">&lt;/key&gt;</span>
  <span class="nt">&lt;string&gt;</span>/Users/zhgchgli/Documents/actions-runner<span class="nt">&lt;/string&gt;</span>
 <span class="nt">&lt;/dict&gt;</span>
<span class="nt">&lt;/plist&gt;</span>
</code></pre></div></div>

<blockquote>
  <p><em>DevOps に興味がある方は、公式の <a href="https://docs.github.com/en/actions/concepts/runners/about-actions-runner-controller#scaling-runners" target="_blank">k8s Runner</a> ドキュメントをご覧ください。</em></p>
</blockquote>

<h4 id="完全なプロジェクトリポジトリ">完全なプロジェクトリポジトリ</h4>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo" target="_blank"><img src="https://opengraph.githubassets.com/eb233d74ad1bc6b0eceb9494487579557fb7f17066a3981d20b52fde2c00ef45/ZhgChgLi/github-actions-ci-cd-demo" alt="" /></a></p>

<h3 id="公式ドキュメント">公式ドキュメント</h3>

<p><a href="https://docs.github.com/en/actions/get-started/quickstart" target="_blank"><img src="https://docs.github.com/assets/cb-345/images/social-cards/actions.png" alt="" /></a></p>

<p>より詳細な設定方法については、必ず公式マニュアルを参照してください。</p>

<h4 id="aiが助けになる">AIが助けになる！</h4>

<p><img src="/assets/404bd5c70040/1*JecNUCqujV1oeAvHA14X-g.webp" alt="" loading="lazy" decoding="async" width="1114" height="1140" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTE0IiBoZWlnaHQ9IjExNDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/404bd5c70040/1*JecNUCqujV1oeAvHA14X-g.png" /></p>

<p>実際にChatGPTに完全な手順とタイミングを伝えるだけで、GitHub Actionsをすぐに作成してくれます！</p>

<h3 id="まとめ">まとめ</h3>

<p>今、GitHub Actions と Self-hosted Runner についてある程度理解できたと思います。次回は App（iOS）CI/CD をケースとして、一連のプロセスを手取り足取り構築していきます。</p>

<h3 id="シリーズ記事">シリーズ記事：</h3>

<ul>
  <li>
    <p><a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/"><strong>CI/CD 実践ガイド（1）：CI/CD とは？CI/CD で安定かつ効率的な開発チームを作るには？ツールの選び方は？</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/"><strong>CI/CD 実践ガイド（二）：GitHub Actions と Self-hosted Runner の使い方と構築大全</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/"><strong>CI/CD 実践ガイド（三）：GitHub Actions を使ったアプリプロジェクトの CI と CD ワークフローの実装</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/"><strong>CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</strong></a></p>
  </li>
</ul>

<h4 id="-buy-me-a-beer-on-paypal"><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank">🍺 Buy me a beer on PayPal</a></h4>

<blockquote>
  <p><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank"><strong><em>本シリーズの記事は多くの時間と労力をかけて執筆しています。内容がお役に立ち、チームの作業効率や製品品質の向上に貢献できた場合は、ぜひコーヒーをご馳走ください。ご支援ありがとうございます！</em></strong></a></p>
</blockquote>

<p><img src="/assets/404bd5c70040/1*QJj54G9gOjtQS-rbHVT1SQ.webp" alt="Buy me a coffee" loading="lazy" decoding="async" width="700" height="700" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiIGhlaWdodD0iNzAwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/404bd5c70040/1*QJj54G9gOjtQS-rbHVT1SQ.png" /></p>

<p><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank">🍺 Buy me a beer on PayPal</a></p>

<p><em><a href="https://medium.com/zrealm-ios-dev/ci-cd-%E5%AF%A6%E6%88%B0%E6%8C%87%E5%8D%97-%E4%BA%8C-github-actions-%E8%88%87-self-hosted-runner-%E4%BD%BF%E7%94%A8%E8%88%87%E5%BB%BA%E7%BD%AE%E5%A4%A7%E5%85%A8-404bd5c70040" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>を使って変換。</em></p>]]></content>
  </entry><entry>
    <title type="html">CI/CD 実践ガイド｜iOS開発チーム向け安定・効率化の秘訣と最適ツール選定</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ci-cd-%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-ios%E9%96%8B%E7%99%BA%E3%83%81%E3%83%BC%E3%83%A0%E5%90%91%E3%81%91%E5%AE%89%E5%AE%9A-%E5%8A%B9%E7%8E%87%E5%8C%96%E3%81%AE%E7%A7%98%E8%A8%A3%E3%81%A8%E6%9C%80%E9%81%A9%E3%83%84%E3%83%BC%E3%83%AB%E9%81%B8%E5%AE%9A-c008a9e8ceca/" rel="alternate" type="text/html" title="CI/CD 実践ガイド｜iOS開発チーム向け安定・効率化の秘訣と最適ツール選定" />
    <published>2025-06-30T15:10:16+08:00</published>
    <updated>2025-12-18T00:24:11+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/c008a9e8ceca</id><summary type="html">iOSアプリ開発チームが抱える効率化課題を解決。CI/CD導入で開発速度と品質を向上させる方法と具体的ツール選びを詳解し、実務での効果を最大化します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="iosアプリ開発" /><category term="ci-cd" /><category term="github-actions" /><category term="jenkins" /><category term="アジャイル" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/c008a9e8ceca/1*vokpvb4dyWHOnVnF3WGbfw.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/ci-cd-%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-ios%E9%96%8B%E7%99%BA%E3%83%81%E3%83%BC%E3%83%A0%E5%90%91%E3%81%91%E5%AE%89%E5%AE%9A-%E5%8A%B9%E7%8E%87%E5%8C%96%E3%81%AE%E7%A7%98%E8%A8%A3%E3%81%A8%E6%9C%80%E9%81%A9%E3%83%84%E3%83%BC%E3%83%AB%E9%81%B8%E5%AE%9A-c008a9e8ceca/"><![CDATA[<h3 id="cicd-実践ガイド1cicd-とはcicd-を使って安定かつ効率的な開発チームを作るにはツールの選び方">CI/CD 実践ガイド（1）：CI/CD とは？CI/CD を使って安定かつ効率的な開発チームを作るには？ツールの選び方？</h3>

<p>App（iOS）チームを例に、CI/CDの基本から導入後にもたらす実質的な価値までご紹介します。</p>

<p><img src="/assets/c008a9e8ceca/1*vokpvb4dyWHOnVnF3WGbfw.webp" alt="Photo by Leif Christoph Gottwald" loading="lazy" decoding="async" width="1200" height="675" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY3NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/c008a9e8ceca/1*vokpvb4dyWHOnVnF3WGbfw.jpeg" /></p>

<p>Photo by <a href="https://unsplash.com/@project2204?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash" target="_blank">Leif Christoph Gottwald</a></p>

<h3 id="2026年アップデート--github-actionsの価格変更self-hosted-runnerを含む">2026年アップデート — GitHub Actionsの価格変更（Self-hosted Runnerを含む）</h3>

<blockquote>
  <p><a href="https://resources.github.com/actions/2026-pricing-changes-for-github-actions/" target="_blank">TLDR — 2026年1月1日より、ホスト型ランナーの料金を引き下げ、2026年3月1日からセルフホスト型ランナーに対して1分あたり0.002ドルの課金を開始します。ほとんどのユーザーの請求額には変更ありません。パブリックリポジトリでのActionsは引き続き無料です。</a></p>
</blockquote>

<p>GitHub 2025/12/14 <a href="https://resources.github.com/actions/2026-pricing-changes-for-github-actions/" target="_blank">最新のお知らせ</a> ：</p>

<ul>
  <li>
    <p>2026年1月1日：GitHub-hosted Runnerの料金がさらに安くなり、最大39%割引されました。</p>
  </li>
  <li>
    <p>2026年3月1日：<strong>Self-hosted Runnerを使用する場合、サービス運用費として1分あたり0.002ドル（OS問わず）が追加で発生します。つまり500分で1ドルのコストですが、現時点では依然としてお得です。</strong>️</p>
  </li>
  <li>
    <p>Publicリポジトリは引き続き同じ無料枠が維持されます。</p>
  </li>
</ul>

<p><strong>GitHub も GitHub Actions の機能強化により多くのリソースを投入します：</strong></p>

<ul>
  <li>
    <p><strong>Scale Set Client：</strong> Self-hosted Runner の <strong>オートスケーリング</strong> を簡素化。</p>
  </li>
  <li>
    <p><strong>multi-label：再起動をサポート</strong>し、Runnerのラベル体験を改善。</p>
  </li>
  <li>
    <p><strong>Actions Runner Controller (ARC)</strong> のアップデート：構成、可観測性、バージョン管理の向上。</p>
  </li>
  <li>
    <p><strong>Actions Data Stream：</strong> ワークフローやランナーのイベントデータをほぼリアルタイムでストリーミングし、監視や分析に活用可能。</p>
  </li>
</ul>

<p><a href="https://github.com/pricing/calculator" target="_blank"><strong>公式の価格計算ツールも更新されました</strong></a> <strong>：</strong></p>

<p><img src="/assets/c008a9e8ceca/1*CuNXq0t_70UiVY0N3JEacA.webp" alt="" loading="lazy" decoding="async" width="1144" height="921" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQ0IiBoZWlnaHQ9IjkyMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/c008a9e8ceca/1*CuNXq0t_70UiVY0N3JEacA.png" /></p>

<ul>
  <li>
    <p>GitHub Hosted Runner — macOS 3コア(M1): $0.062 USD/分、1,000分で $62 USD</p>
  </li>
  <li>
    <p>Self-Hosted Runner — $0.002 USD/分、1,000分で $2 USD</p>
  </li>
</ul>

<blockquote>
  <p><em>最新モデルの<a href="https://www.apple.com/tw/shop/buy-mac/mac-mini" target="_blank">Mac Mini 10-core(M4)</a>を約600ドルUSDで購入し、オフィスにSelf-hosted Runnerとして設置すれば、約1年で元が取れます。性能が高く速い上に、使用量はほぼ無制限（<strong>維持費はほとんどかかりません</strong>）。</em></p>
</blockquote>

<blockquote>
  <p><em>古い M1 MacBook Pro を Runner として使うこともでき、費用は 0 円です。</em></p>
</blockquote>

<blockquote>
  <p>*上記には電気代とネット費用は含まれていません。</p>
</blockquote>

<h4 id="はじめに">はじめに</h4>

<p>異なる開発チームで2回にわたりAppのCI/CDを構築した経験を経て、最近ようやく「なぜやるのか」から「どうやるのか」までの過程を整理する時間ができました。最も標準的なCI/CDワークフローとは限りませんが、チームが導入を始め、製品の安定性と開発効率を向上させるための参考になる出発点であることは間違いありません。</p>

<h4 id="章節">章節</h4>

<p>本シリーズ記事は「CI/CDとは何か、どんな価値をもたらすか」から始まり、次に「GitHub Actions + self-hosted Runnerを使ったCI/CD環境の構築」を手取り足取り実践します。そして「アプリ開発を例に、実際にCIとCDを導入する方法」を紹介し、最後に「Google Apps Script Web AppとGitHub Actionsを組み合わせて、チーム間で使いやすいアプリパッケージングプラットフォームを作る方法」も解説します。このシリーズが皆さんの役に立てば幸いです。</p>

<ul>
  <li>
    <p><a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/"><strong>CI/CD 実践ガイド（1）：CI/CD とは？CI/CD を使って安定かつ効率的な開発チームを作るには？ツールの選び方は？</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/"><strong>CI/CD 実践ガイド（二）：GitHub Actions と self-hosted Runner の使い方と構築完全版</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/"><strong>CI/CD 実践ガイド（三）：GitHub Actions を使ったアプリプロジェクトの CI と CD ワークフローの実装</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/"><strong>CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</strong></a></p>
  </li>
</ul>

<h4 id="最終成果">最終成果</h4>

<p>無駄話は抜きにして、まずは最終結果をお見せします。</p>

<p><img src="/assets/c008a9e8ceca/1*7-abScyjHQno1XzH4aGkaw.webp" alt="Demo PR" loading="lazy" decoding="async" width="1265" height="1093" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjY1IiBoZWlnaHQ9IjEwOTMiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/c008a9e8ceca/1*7-abScyjHQno1XzH4aGkaw.png" /></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/pull/11" target="_blank">Demo PR</a></p>

<p><img src="/assets/c008a9e8ceca/1*yXMeaOELhqdvMCxIJ5ElBw.gif" alt="Demo Web App（初回利用は下記のチュートリアルを参照してください）" loading="lazy" decoding="async" width="1048" height="822" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDQ4IiBoZWlnaHQ9IjgyMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<p><a href="https://script.google.com/macros/s/AKfycbwNW6N5ozKbIz_E1HK6yFEUtA8KQrUciS-jcPsQptvIKlARmKgLxbQzNu8ksVeg-BmEfg/exec" target="_blank">Demo Web App（初回利用は下記のチュートリアルをご参照ください）</a></p>

<p>CI/CD — すべて GitHub Actions を使って開発しているので、保守しやすく拡張もしやすい。</p>

<p><strong>CI（継続的インテグレーション）:</strong></p>

<ul>
  <li>
    <p>PRを送ると自動でユニットテストが実行される</p>
  </li>
  <li>
    <p>変更されたファイル範囲に応じて対応するテストを実行する</p>
  </li>
  <li>
    <p>テストが合格してからでないとPRをマージできません</p>
  </li>
</ul>

<p><strong>CD:</strong></p>

<ul>
  <li>
    <p>Google Apps Script Web App（CDパッケージングインターフェース）は、エンジニア、QA、PMがパソコンやスマホからアプリをパッケージングできるウェブサイトです。</p>
  </li>
  <li>
    <p>GitHub Actions Self-hosted Runner 自分のマシンでCI/CDを実行し、使用量無制限</p>
  </li>
  <li>
    <p>Firebase App Distribution API と連携して、ビルドしたテスト版のダウンロードリンクを直接取得する</p>
  </li>
</ul>

<p><strong>自動化</strong> :</p>

<ul>
  <li>
    <p>PRを作成すると自動で自分にアサインする</p>
  </li>
  <li>
    <p>PRを作成するとランダムにレビュアーを割り当てる</p>
  </li>
  <li>
    <p>PRサイズラベルの設定</p>
  </li>
</ul>

<h4 id="デモ-web-アプリプロジェクト">デモ Web アプリ/プロジェクト</h4>

<ul>
  <li><a href="https://script.google.com/macros/s/AKfycbwNW6N5ozKbIz_E1HK6yFEUtA8KQrUciS-jcPsQptvIKlARmKgLxbQzNu8ksVeg-BmEfg/exec" target="_blank">Online Demo</a> 初めてご利用の方は、以下の図の許可設定をご参照ください（デモアプリ専用）：</li>
</ul>

<p><img src="/assets/c008a9e8ceca/1*0cD7NrUr9J9roqIe4Upfzg.webp" alt="" loading="lazy" decoding="async" width="1200" height="1041" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwNDEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/c008a9e8ceca/1*0cD7NrUr9J9roqIe4Upfzg.png" /></p>

<p><a href="https://script.google.com/home/projects/1CBB39OMedqP9Ro1WSlvgDnMBin4-ksyhgly2h_KrbOuFiPHTalNgwHOp/edit?pli=1" target="_blank"><img src="https://www.gstatic.com/devrel-devsite/prod/v78ce60439c72b9da3632137223a86ae38b78a872a1f6dee1b5c1c8cfa57fe81d/developers/images/opengraph/white.png" alt="" /></a></p>

<p><a href="https://github.com/ZhgChgLi/github-actions-ci-cd-demo/" target="_blank"><img src="https://opengraph.githubassets.com/eb233d74ad1bc6b0eceb9494487579557fb7f17066a3981d20b52fde2c00ef45/ZhgChgLi/github-actions-ci-cd-demo" alt="" /></a></p>

<h3 id="cicd-とは何ですか">CI/CD とは何ですか？</h3>

<h4 id="ストーリー--cicdなしの開発フロー">ストーリー — CI/CDなしの開発フロー</h4>

<p>CI/CDとは何かを語る前に、まず「CI/CD」という言葉を置いておいて、何のワークフローも導入していないスタートアップの開発チームがどのように仕事をしているかを振り返ってみましょう。おおまかには以下の図のような流れです：</p>

<p><img src="/assets/c008a9e8ceca/1*rg4hbs7MsYDU9HZoehrvjQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="687" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjY4NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/c008a9e8ceca/1*rg4hbs7MsYDU9HZoehrvjQ.png" /></p>

<ol>
  <li>
    <p>製品にバグがあり、Developer T は main ブランチから fix/bug-c ブランチを切って修正を行い、修正完了後に main ブランチへマージしました。</p>
  </li>
  <li>
    <p>続いて Developer Z は main ブランチから feature/a ブランチを切り、要件 A を進めていたが、途中で機能がおかしいことに気づきました。<strong>調べたところ、現在の機能が壊れており、テストも失敗していることが判明した</strong>ため、Developer T に修正を依頼しました。</p>
  </li>
  <li>
    <p>すべての開発が完了した後、Developer Z は <strong>自分のパソコンでビルドしたバージョンを QA に渡してテストし、何度も修正とビルドを繰り返しました</strong>。最終的に問題がなければ機能を main ブランチにマージします。</p>
  </li>
  <li>
    <p>すぐにスプリントの終わりが来て、リリース用のパッケージを作成してユーザーに提供する必要があります。Developer Z は <strong>手元の作業を一旦中断し</strong>、main ブランチからパッケージを作成して QA に回帰テストを依頼します。同様に <strong>問題を何度も修正し再パッケージを行い</strong>、完了後に審査用のアプリをパッケージして提出します。</p>
  </li>
  <li>
    <p>Apple/Google の審査完了後、ユーザーにリリースされます。</p>
  </li>
</ol>

<h4 id="問題">問題</h4>

<p>以上のストーリーから、2つの大きな問題点をまとめることができます。</p>

<p><strong>Question 1: 現在の正しい機能変更に対して統一された検査機構が全くありません。</strong></p>

<ul>
  <li>
    <p>コーディングスタイルに合わないコードもマージ可能</p>
  </li>
  <li>
    <p>ビルドに失敗してもマージできる</p>
  </li>
  <li>
    <p>変更後、基本的なユニットテストや重要なチェック項目が通らなくてもマージできる</p>
  </li>
  <li>
    <p>私の環境では機能は正しく動作していますが、他の人の環境では必ずしも正しく動作するとは限りません。</p>
  </li>
  <li>
    <p>他の開発中のメンバーに影響を与える</p>
  </li>
</ul>

<p><strong>質問2: パッケージ作業に多くの人手と時間がかかっている。</strong></p>

<ul>
  <li>
    <p>パッケージングはエンジニアの手作業で行うため、現在の開発作業が中断される。</p>
  </li>
  <li>
    <p>パッケージングと開発を行き来する際、フローの切り替えコストが非常に高い。</p>
  </li>
  <li>
    <p>パッケージ作成の待機時間中は他の開発作業ができない。</p>
  </li>
  <li>
    <p>エンジニアの時間コストはつまりお金です。</p>
  </li>
  <li>
    <p>手動操作はミスが起こる可能性があります。</p>
  </li>
  <li>
    <p>QAはエンジニアにパッケージングを依頼するため、やり取りが発生します。</p>
  </li>
</ul>

<h4 id="ci--continuous-integration-継続的インテグレーション">CI — Continuous Integration 継続的インテグレーション</h4>

<p>Question 1 に対応する「継続的インテグレーション（CI）」は、すべての変更が自動的に統一された環境でビルドとテストを実行し、本番環境に入る前にすべてのテストケースを通過しチームの規範に適合していることを保証することを目的としています — 「継続的に正しいコードが本番環境に統合されることを自動的に保証する」ことです。</p>

<p>また、Nightly Build やより多くの自動テスト工程を追加して、安定性を確保することもできます。</p>

<h4 id="cd--continuous-delivery--deployment-継続的デリバリーデプロイメント">CD — Continuous Delivery / Deployment 継続的デリバリー／デプロイメント</h4>

<p>Question 2「継続的デプロイメント」は、CI段階でコードに異常がないことを確認した後、変更内容を自動でパッケージ化し、社内テスト（QA、デバッグ、ステージング、ベータなど）や外部リリース（プロダクション、リリースなど）へ展開する煩雑な作業を自動化することを目的としています。</p>

<ul>
  <li>
    <p><strong>Continuous Deployment:</strong> 完全に自動で直接 Production 環境へデプロイすること</p>
  </li>
  <li>
    <p><strong>Continuous Delivery:</strong> Staging/Debug 環境への自動デプロイのみ行い、問題がないことを手動で確認してから Production 環境にデプロイする方式</p>
  </li>
</ul>

<p>App開発のシナリオに応じて、より<strong>Continuous Delivery（継続的デリバリー）</strong>に近いです。私たちは、Appが最終的にリリースされる前に人の目で問題がないことを確認してから公開し、リリースのタイミングと機能の正確性を保証したいと考えています。</p>

<h4 id="ストーリー--cicdを通じて安定かつ効率的な開発チームを作る">ストーリー — <strong>CI/CDを通じて安定かつ効率的な開発チームを作る</strong></h4>

<p><img src="/assets/c008a9e8ceca/1*rszgT5yFKCcfCUka_t9b3g.webp" alt="" loading="lazy" decoding="async" width="1200" height="824" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/c008a9e8ceca/1*rszgT5yFKCcfCUka_t9b3g.png" /></p>

<p><strong>私たちのストーリーを振り返ると、CI/CD 導入後：</strong></p>

<ul>
  <li>
    <p>CI<br />
すべての変更は自動テストの検証を通過してからメインブランチにマージされる必要があり、Nightly Buildによる定期的な自動テストを追加して安定性を向上させます。</p>
  </li>
  <li>
    <p>CD<br />
すべてCDでパッケージングを統一することで、Developer TとDeveloper Zは業務開発に完全に集中でき、手動のコミュニケーションや操作ミスを減らせます。</p>
  </li>
</ul>

<blockquote>
  <p>チームの作業効率と製品の安定性 🚀🚀🚀🚀🚀</p>
</blockquote>

<h3 id="cicd-の価値">CI/CD の価値</h3>

<p>アジャイル開発の核心理念である「小さなステップで素早く進む、迅速な反復」に対して、CI/CDは「頻繁で継続的な機能の反復」の安定性と作業効率の基盤を提供します。</p>

<p><strong>自動で反復結果の検証を統一</strong></p>

<ul>
  <li>すべての調整が正しい期待結果を満たし、他の機能や他のメンバーに影響を与えないことを確認する</li>
</ul>

<p><strong>面倒なデプロイ作業の自動化</strong></p>

<ul>
  <li>チームメンバーが主要な業務開発に集中できるようにし、手動操作ミスを減らすことができる</li>
</ul>

<h4 id="cicd-の効果">CI/CD の効果</h4>

<p>2021年にPinkoiで行った講演「<a href="/posts/pinkoiエンジニアリング/pinkoi-tech-talk-高効率エンジニアチームの秘密を徹底解説-11f6c8568154/"><strong>2021 Pinkoi Tech Career Talk — 高効率エンジニアチーム大解密</strong></a>」を振り返ると、内容はほぼ同じで、「自動化、人と人の依存を減らす、主要業務に集中する」という点に尽きます。CI/CDの導入もまさにこの3つの方向に合致しており、同じ方法で効果を見積もることができます。</p>

<p><strong>もう一点、再度強調したいのは <a href="https://zh.wikipedia.org/wiki/%E5%BF%83%E6%B5%81%E7%90%86%E8%AB%96" target="_blank">心の切り替えコスト</a> です：</strong></p>

<p><img src="/assets/c008a9e8ceca/1*xOzjG-lSiFmdT-C4GHf0JA.webp" alt="" loading="lazy" decoding="async" width="960" height="540" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjAiIGhlaWdodD0iNTQwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/c008a9e8ceca/1*xOzjG-lSiFmdT-C4GHf0JA.png" /></p>

<p>私たちが一定時間継続して作業を行うと、「フロー」状態に入ります。この時、思考や生産性はピークに達し、最も効果的なアウトプットが可能になります。しかし、一度中断されると、再びフローに戻るまでに時間がかかります。ここでは30分を例とします。</p>

<p><strong>CI/CD がない場合のシナリオは次のようになります：</strong> 問題が改悪されたことに気づくまでに多くの時間がかかり、その後コミュニケーションして修正する（CI）、QAやPMがエンジニアにテスト版アプリのビルドを依頼する（CD）。</p>

<h4 id="cicd-効果の見積もり">CI/CD 効果の見積もり</h4>

<p><img src="/assets/c008a9e8ceca/1*SinoHlHKbtXiRubUS8Bm9Q.webp" alt="チーム人数 6人 / 1ヶ月の計算" loading="lazy" decoding="async" width="1200" height="790" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/c008a9e8ceca/1*SinoHlHKbtXiRubUS8Bm9Q.png" /></p>

<p>チーム人数 6人 / 1ヶ月で計算</p>

<p>ここでは月単位を基準とし、CI/CDプロセスがない場合、毎月4回メインブランチが誤って壊れる事故が発生し、その修正やコミュニケーションに約720分かかると仮定します。さらに、毎月のテスト版や正式版のビルド、および手動操作によるミスの可能性を含めると、合計で約1,010分かかります。エンジニアの月給を8万円とすると、毎月約1万3千円のコストが無駄になっている計算です。</p>

<blockquote>
  <p><em>ここで見落としていたのは、<a href="https://resources.github.com/actions/2026-pricing-changes-for-github-actions/" target="_blank">2026–03–01 以降 Self-hosted は1分あたり0.002 USD の維持費が必要</a> という点で、500分実行すると1 USDの費用がかかることです。</em></p>
</blockquote>

<h4 id="cicd-構築コスト">CI/CD <strong>構築コスト</strong></h4>

<ul>
  <li>
    <p>人件費用：<br />
本シリーズの記事に沿って構築すると、概算で1人が10日間 = <strong>4,800分</strong> の作業時間が必要です。(~= <strong>NT$36,384</strong>)</p>
  </li>
  <li>
    <p>設備と実行コスト：<br />
GitHub Actions の self-hosted Runner を使用する場合、初期に 1～2 台の <a href="https://www.apple.com/tw/shop/buy-mac/mac-mini/m4" target="_blank">Mac-Mini</a> を購入するか、既存の古くなった MacBook Pro をそのまま CI/CD Runner として利用できます。<br />
6人チームで新品の Mac Mini を1台購入する場合の例：32GB RAM M4 Mini (= <strong>NT$40,900</strong> )</p>
  </li>
</ul>

<p>総費用は約 <strong>NT$80,000</strong> で構築でき、約半年後に効果を享受し始めます。</p>

<blockquote>
  <p><strong><em>声明：</em></strong> <em>ここでは効果測定の一例を示しているだけで、必ずしも最も正確な方法ではありません。あくまで概念を理解し、<strong>経営層がCI/CDの効果を把握して</strong> 推進の承認を得るための参考としてください。</em></p>
</blockquote>

<h3 id="cicd-のツール選択">CI/CD のツール選択</h3>

<h4 id="クラウドサービス-bitrise--xcode-cloud">クラウドサービス Bitrise / XCode Cloud</h4>

<ul>
  <li>
    <p><strong>Bitrise：</strong> 最初はAppのCI/CDを提供するクラウドサービスとして有名で、私が初めてCI/CDに触れたのもBitriseでした。直感的に使えるステップ編集ツールがあり、AppのCI/CDプロセスを素早く設定できます。<br />
<strong>欠点：</strong> 初期は月額99ドルの使い放題でしたが、AppleのMシリーズプロセッサが登場した際に従量課金制（<strong>囲い込み戦略</strong>）に変更されました。その時、チームの利用量で月に少なくとも500ドルはかかる見込みだったため、GitHub Actionsに移行しました。<br />
ただ、最近公式サイトを見ると、現在は1アプリ／1同時実行／使い放題で月額89ドルのプランを提供しています。</p>
  </li>
  <li>
    <p><strong>XCode Cloud：</strong> 100時間／1ヶ月／50ドル、XCodeやApp開発と高度に統合されているのが利点です。しかし、欠点としてはAndroidには対応しておらず、一部のカスタマイズが難しい点があります。純粋なiOSの小規模Appであれば、再度直接利用を検討します。</p>
  </li>
</ul>

<blockquote>
  <p><em>クラウドサービスの「囲い込み」リスクを非常に懸念しており、コントロールを自分たちで持ちたいので、オンプレミスサービスを検討しています。</em></p>
</blockquote>

<h4 id="ローカルサービス-jenkins--github-actions--gitlab-cicd">ローカルサービス Jenkins / GitHub Actions / Gitlab CI/CD</h4>

<ul>
  <li>
    <p><strong>Gitlab CI/CD：</strong><br />
GitHub Actions よりも早くリリースされ、機能も充実していますが、私たちのプロジェクトは GitHub 上でホスティングされているため、Gitlab CI/CD は検討しませんでした。ただし、両者の機能は似ているため、本シリーズの記事では GitHub Actions を例に説明します。</p>
  </li>
  <li>
    <p><strong>GitHub Actions</strong><br />
GitHubが2018年にリリースしたCI/CDサービスで、GitHubプロジェクトと直接連携します。ここ数年で機能が継続的に改善され、多くのパッケージ化されたステップ（<a href="https://github.com/marketplace?type=actions" target="_blank">Marketplace</a>）がすぐに使えます。self-hosted runnerもサポートしており、自分のマシンで無制限に利用可能です。（いわばハイブリッドクラウドです）</p>
  </li>
  <li>
    <p><strong>Jenkins：</strong><br />
CI/CD 専用のオープンソースで無料のツールで、古いですが機能は強力です。アプリケーション層のタスク設計や権限管理から、低レベルのサービス配信と実行まで、Jenkins はすべてをカバーします。同様に <a href="https://plugins.jenkins.io/" target="_blank">Plugins</a> が利用でき、初期の DevOps CI/CD に必須のツールです。</p>
  </li>
</ul>

<h3 id="jenkins-vs-github-actions">Jenkins v.s. GitHub Actions</h3>

<h4 id="tldr"><strong>TL;DR</strong></h4>

<blockquote>
  <p><em>DevOps 専任者がいない App チームでは、App 開発者が Jenkins 環境をゼロから構築・維持するのはハードルが高く、扱える人も少ないためネットワークセキュリティの問題も発生しやすいです。そこで GitHub Actions を直接利用することを選択し、App 開発者は CI/CD フロー設計に専念するだけで、公式ドキュメントを軽く確認し Runner の起動方法を覚えれば、無料で安定かつ安全な CI/CD サービスを素早く構築できます。</em></p>
</blockquote>

<p><img src="/assets/c008a9e8ceca/1*qg8SkzoJqNVvWPxx2Lh6uA.webp" alt="" loading="lazy" decoding="async" width="504" height="434" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MDQiIGhlaWdodD0iNDM0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/c008a9e8ceca/1*qg8SkzoJqNVvWPxx2Lh6uA.png" /></p>

<blockquote>
  <p><em>以下はアプリのCI/CD構築を出発点とした比較であり、すべての技術シナリオに適用されるわけではありません。</em></p>
</blockquote>

<h4 id="構築と維持の難易度-jenkins--github-actions"><strong>構築と維持の難易度</strong> Jenkins &gt;&gt;&gt; GitHub Actions</h4>

<p><img src="/assets/c008a9e8ceca/1*k2XGXjV_VZEt618DnDm0lA.webp" alt="" loading="lazy" decoding="async" width="999" height="1117" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5OTkiIGhlaWdodD0iMTExNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/c008a9e8ceca/1*k2XGXjV_VZEt618DnDm0lA.png" /></p>

<p>ここではあまり専門的でない構造の階層図を使って両者の違いを説明します。Jenkinsは前述の通り上から下まで全機能をカバーしているため、自前で構築するとかなり複雑になります。一方、GitHub ActionsはGitHub上でYAMLワークフローを書くだけでよく、ローカルマシンにはGitHub self-hosted Runnerを登録するだけ（5つのコマンドで完了）で、GitHubが自動的にタスクをローカルマシンに割り当てます。その他、GitHub Actions/Runnerのバージョンアップやタスク割り当ての問題はGitHubが管理してくれるため、私たちが対応する必要はありません。</p>

<p>もう一つ厄介な点は、JenkinsがGitとは独立したサービスであり、API（例：GitHub API/WebHook）を通じて連携するため、設定がさらに複雑になることです。</p>

<p>以前、身近なiOS開発者（約30名）に調査を行ったところ、Jenkinsを理解しているのはごくわずか（2名）で、GitHub Actionsを使用しているのは10名以上でした。やはりYAMLを書くだけでCI/CDのタスクを完了できるのが理由です。</p>

<h4 id="学習難易度-jenkins-github-actions">学習難易度 Jenkins »&gt; GitHub Actions</h4>

<p>同様に、公式ドキュメントを参照して、GitHub Actionsで使用可能なYAMLコマンドとローカルで自分のRunnerを起動する方法を学ぶだけで十分です。</p>

<h4 id="安定性-github-actions--jenkins">安定性 GitHub Actions &gt; Jenkins</h4>

<p>この点については、GitHub ActionsがJenkinsよりやや優れていると感じます。</p>

<p>Jenkins はシステムのアップグレードや競合するプラグインのインストールによりサービスがクラッシュする可能性があります（ただし、問題なく動作している場合は基本的に触らなければ問題ありません）。</p>

<p>GitHub Actions は <a href="https://www.githubstatus.com/" target="_blank">GitHub サービスステータス</a> に依存しているため（GitHub がダウンすると連動して停止します）が、発生頻度は低く、平均稼働率は 99.9% を維持しています。問題が起きても対応は不要で、修復を待つだけで済みます。</p>

<h4 id="セキュリティ-github-actions--jenkins">セキュリティ GitHub Actions &gt; Jenkins</h4>

<p>GitHub Actions/Runner サービス自体が GitHub によってメンテナンスおよび自動更新されるため、Jenkins の手動更新よりも安全である可能性があります。</p>

<p>また、Jenkins と GitHub の間で API/WebHook ポートを開く必要があるため、比較的リスクがあります。GitHub と GitHub Actions の間はシームレスに統合されており、GitHub Actions と self-hosted Runner の間はオブザーバーモードです。self-hosted Runner は GitHub からタスクを受け取るため、Runner 自体が外部にポートを開く必要はありません。</p>

<p>しかし、完全に閉じたネットワーク環境の場合、Jenkinsの方がGitHub Actionsより安全です。</p>

<h4 id="権限管理-jenkins-github-actions">権限管理 Jenkins »&gt; GitHub Actions</h4>

<p>この点は特に比較する必要があります。Jenkins は別途アカウントログイン権限を設定して管理できますが、GitHub Actions は直接 GitHub リポジトリと連携しており、リポジトリ権限を持つ人のみが使用可能です。</p>

<blockquote>
  <p><strong>だからこそ、後半の記事では GAS Web App を使ってチーム間で共有可能な操作プラットフォームを構築しています。</strong></p>
</blockquote>

<h4 id="jenkins-より-github-actions-を優先して使用する">Jenkins より GitHub Actions を優先して使用する</h4>

<p>完全な DevOps チームがある場合、間違いなく Jenkins を選ぶでしょう。なぜなら、他の分野（例えば Web、バックエンド、Java など）では Jenkins が最も長く稼働しており、プラグインも豊富で使いやすいからです。また、CI/CD サービスを統一してすべてのチームで利用しやすく管理できることや、バックエンドのデプロイ完了後にフロントエンドを自動デプロイするといった複雑な CI/CD シナリオにも対応可能です。</p>

<blockquote>
  <p><strong>GitHub Actions は後にクロスリポジトリアクション/ランナーもサポートしました。</strong></p>
</blockquote>

<h4 id="サードパーティ製パッケージの豊富さ-jenkins--github-actions">サードパーティ製パッケージの豊富さ Jenkins &gt; GitHub Actions</h4>

<p>数の面では GitHub Actions が Jenkins を上回っていますが、Jenkins の CI/CD 機能はより深く強力です。GitHub Actions は多くが単なる自動化機能に過ぎません。</p>

<h4 id="機能の深さ-jenkins-github-actions">機能の深さ Jenkins »&gt; GitHub Actions</h4>

<p>この点は比較になりません。Jenkinsは約20年の実績がありますが、GitHub Actionsはまだ多くの機能を補う必要があります。例えば、権限管理、Secret管理（現在はテキストのみ対応で、鍵ファイルは先にテキスト化が必要）、Cache/Artifactも現状はクラウドのみ対応などです。</p>

<p><strong>さらに、GitHub Self-hosted Runner は <a href="https://docs.github.com/en/actions/concepts/runners/about-actions-runner-controller#scaling-runners" target="_blank">Docker や k8s</a> にも対応しています。</strong></p>

<h4 id="カスタマイズの深さ-jenkins-github-actions">カスタマイズの深さ Jenkins »&gt; GitHub Actions</h4>

<p>Jenkins は最初から最後まで自分で管理できるため、カスタマイズの自由度が高く、システム全体に影響を与えることができます。一方、GitHub Actions はアプリケーション層でのステップごとのカスタマイズに限られます。</p>

<p>例えば現在の GitHub Actions の内蔵 Artifacts は self-hosted をサポートしていないため、ステップ内で sh を使って別のディレクトリにコピーするしかなく、Artifacts を独自にカスタマイズして実現することはできません。</p>

<blockquote>
  <p><strong>App CI/CD のシナリオでは、高度な機能はあまり必要ありません。</strong></p>
</blockquote>

<h4 id="使いやすさ-github-actions-jenkins">使いやすさ GitHub Actions »&gt; Jenkins</h4>

<p>インターフェース上、GitHub Actions は新しいツールであり、Jenkins よりも使いやすいです。スクリプト設定では、Jenkins は Pipeline Script を Jenkins 上に保存しますが、GitHub Actions は YAML ファイルがプロジェクトの Git と一緒に管理されるため、Jenkins よりも設定が簡単です。</p>

<h4 id="費用リスク-jenkins--github-actions">費用リスク Jenkins &gt; GitHub Actions</h4>

<p>Jenkins は完全にオープンソースで無料で利用できるのに対し、GitHub Actions は一部オープンソースですが、ジョブの割り当てと実行は GitHub のクローズドな SaaS サービスです。現在の方針では、GitHub Actions 自体は完全無料で、GitHub の Runner を使う場合のみ料金が発生します。self-hosted Runner を使用する場合は、<a href="https://resources.github.com/actions/2026-pricing-changes-for-github-actions/" target="_blank">2026年3月1日以降、1分あたり0.002ドルの維持費用が必要になります</a>。なお、Public リポジトリには無料枠があります。</p>

<h3 id="google-apps-script-web-app-の用途と選択理由">Google Apps Script Web App の用途と選択理由</h3>

<p>もう一つのツールの選択肢は Google Apps Script Web App です。これを追加で使う理由は、GitHub Actions に内蔵されているフォーム機能があまりにもシンプルすぎる（インターフェースがエンジニア向けで静的にしか使えない）ことと、実行権限が GitHub リポジトリに紐づいているため、他の職能パートナーに提供するのが非常に面倒だからです。</p>

<p><strong>以下の通り：</strong></p>

<p><img src="/assets/c008a9e8ceca/1*kULMefCX5D6I5z9xt71A5A.webp" alt="" loading="lazy" decoding="async" width="348" height="447" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNDgiIGhlaWdodD0iNDQ3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/c008a9e8ceca/1*kULMefCX5D6I5z9xt71A5A.png" /></p>

<p>CD のパッケージ作成では、操作する人にリリースノートなどの情報を入力してもらいたい場合があります。</p>

<p>したがって、他のメンバーや自分のエンジニアがより使いやすいように、「インターフェース」ツールが必要です。</p>

<p><strong>必要な状況：</strong></p>

<blockquote>
  <p><em>この使いやすい「インターフェース」で必要な情報を入力し、プロジェクト管理ツール（例：Jira、Asana）からタスクを取得したり、GitHubから直接PRリストを取得したりして、プルダウンメニューから選択して送信します。するとGitHub APIを通じてGitHub Actionsがトリガーされ、ビルドが実行されます。</em></p>
</blockquote>

<h4 id="slack">Slack</h4>

<p>初めて CI/CD を導入した際に、Slack API と連携して以下のような効果を実現しました：</p>

<p><img src="/assets/c008a9e8ceca/1*m85bTTlrwAmCxoVqVXo2fg.webp" alt="&lt;https://slack.com/intl/ja-jp/blog/productivity/workflow-builder-tools-automation-examples&gt;" loading="lazy" decoding="async" width="647" height="497" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NDciIGhlaWdodD0iNDk3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/c008a9e8ceca/1*m85bTTlrwAmCxoVqVXo2fg.png" /></p>

<p><a href="https://slack.com/intl/zh-tw/blog/productivity/workflow-builder-tools-automation-examples" target="_blank">https://slack.com/intl/zh-tw/blog/productivity/workflow-builder-tools-automation-examples</a></p>

<ul>
  <li>パートナーは Slack 内のフォームに情報を入力し、CD ビルドをトリガーして、Slack 通知を受け取ることができます。</li>
</ul>

<p>操作が非常にスムーズで、日常のオフィスツール上で統一されている（SSOT）ため再学習は不要です。しかし、その裏には <strong>開発と保守のコストが非常に高い</strong> という問題があります。その一因として、Slack Outgoing-Webhook API のレスポンス要求が非常に厳しく（3秒以内が必要）、基本的に FAAS サービスを使った簡単な連携（例：Cloud Functions、GAS、Lambda…）は除外されます。</p>

<p><strong>以前のやり方は、自動化とバックエンドに興味のあるメンバーが Kotlin+ktor で一からバックエンドサービスを開発し、GCP 上にサーバーを立てて Slack と連携していました。</strong></p>

<blockquote>
  <p><strong><em>開発と保守のコストが非常に高く、引き継ぎも非常に困難。</em></strong></p>
</blockquote>

<h4 id="google-apps-script--web-app">Google Apps Script — Web App</h4>

<p>以前に「 <a href="/posts/zrealm-dev/google-apps-script-web-appでgithub-action-ci-cdを効率化-フォーム連携で開発スピード向上-4cb4437818f2/">Google Apps Script Web App フォームを使って Github Action CI/CD ワークフローを連携する</a> 」を共有しました：</p>

<p><img src="/assets/c008a9e8ceca/1*Gr4PnV2J2AB9cVFuXMLjcA.webp" alt="" loading="lazy" decoding="async" width="1200" height="596" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/c008a9e8ceca/1*Gr4PnV2J2AB9cVFuXMLjcA.png" /></p>

<p><img src="/assets/c008a9e8ceca/1*NJRcY2ULVylZlsKnBtM27A.webp" alt="Demo Web App フォーム URL" loading="lazy" decoding="async" width="428" height="559" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MjgiIGhlaWdodD0iNTU5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/c008a9e8ceca/1*NJRcY2ULVylZlsKnBtM27A.png" /></p>

<p><a href="https://script.google.com/macros/s/AKfycbwNW6N5ozKbIz_E1HK6yFEUtA8KQrUciS-jcPsQptvIKlARmKgLxbQzNu8ksVeg-BmEfg/exec" target="_blank">Demo Web App Form URL</a></p>

<p><strong>Google Apps Script — Web App を使う利点は：</strong></p>

<ul>
  <li>
    <p>ウェブサイト Web</p>
  </li>
  <li>
    <p>Google Workspace 企業アカウントの権限管理と同様に、組織内のGoogleアカウントのみアクセス可能に設定できます。</p>
  </li>
  <li>
    <p><strong>完全無料</strong></p>
  </li>
  <li>
    <p><strong>Function as a Service はサーバーの構築や管理が不要</strong></p>
  </li>
  <li>
    <p>保守や引き継ぎがより簡単</p>
  </li>
  <li>
    <p>スマホからも操作可能です</p>
  </li>
  <li>
    <p><strong>AIがサポート！</strong><br />
<strong>ChatGPTや他のAIツールはGASに詳しく、直接指示してパッケージングフォーム作成やGitHub API連携を依頼できます</strong></p>
  </li>
  <li>
    <p>同様に Jira、Asana、Slack 通知 API とも連携可能です。</p>
  </li>
</ul>

<p>第二のプロモーションでは、GAS Web Appを使ってチームメンバーに提供しました。同様に良い反響があり、Slackとの違いはブックマークにもう一つURLを追加するだけで、パッケージ化が必要なときはそのURLを開いてウェブフォームから操作する点です。</p>

<h3 id="app-cicd-完全なツールフロー">App CI/CD 完全なツールフロー</h3>

<p>ここにまず完全なワークフローを添付します。次回以降で各ツールの使い方と連携方法を順に紹介していきます。</p>

<p><img src="/assets/c008a9e8ceca/1*pQ-2Jj6s2qlvwTrLghJSjg.webp" alt="" loading="lazy" decoding="async" width="1200" height="573" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU3MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/c008a9e8ceca/1*pQ-2Jj6s2qlvwTrLghJSjg.png" /></p>

<h4 id="ツールの役割">ツールの役割：</h4>

<ul>
  <li>
    <p><strong>GitHub Actions</strong> : CI/CD のロジックスクリプトコード</p>
  </li>
  <li>
    <p><strong>GitHub Actions — Self-hosted Runner</strong> : CI/CD を実際に実行する環境で、自分で構築した Runner を使用します。機器購入費用のみ負担すれば、使用量に制限なくタスクを実行可能です。</p>
  </li>
  <li>
    <p><strong>Google Apps Script Web App</strong> : パッケージングは必ずしもエンジニアが担当するわけではないため、他職種のメンバーが使えるプラットフォームが必要です。GAS Web App は、Web ツールを素早く作成し、URL を共有して他の人に操作してもらえます。</p>
  </li>
  <li>
    <p><strong>Asana/Jira</strong> : プロジェクト管理ツールで、GAS Web App と連携し、QA/PM がパッケージ化したいタスクを直接選択できます。</p>
  </li>
  <li>
    <p><strong>Slack</strong> : 実行結果の通知を受け取る担当</p>
  </li>
</ul>

<h4 id="シナリオ">シナリオ：</h4>

<ul>
  <li>
    <p>エンドユーザー（QA/PM/PD/開発者）：GAS Web App を使ってパッケージングフォームを送信（Jira または Asana のタスクに対応するブランチを取得）-&gt; GAS が GitHub API を呼び出す -&gt; CD パッケージングの GitHub Actions をトリガー &lt;- GitHub self-hosted runner がタスクを検知してマシンで実行 -&gt; 実行完了後に Slack 通知、GAS Web App のパッケージング状態を更新。</p>
  </li>
  <li>
    <p>エンドユーザー（開発者）：PRを作成し、新しいコミットをPRにプッシュ -&gt; CIテストプロセスをトリガー &lt;- GitHub self-hosted runnerがジョブを検知してマシンで実行 -&gt; 実行完了後、テスト結果をコメントし、Checksを更新。</p>
  </li>
</ul>

<h3 id="まとめ">まとめ</h3>

<p>本記事では、まず CI/CD が何かとそのメリットについて初歩的に説明します。次回からは技術面に入り、GitHub Actions を使った CI/CD の実装を手取り足取り解説し、前回の記事で紹介した最終成果物の完成まで進めていきます。</p>

<h3 id="シリーズ記事">シリーズ記事：</h3>

<ul>
  <li>
    <p><a href="/posts/zrealm開発/ci-cd-実践ガイド-ios開発チーム向け安定-効率化の秘訣と最適ツール選定-c008a9e8ceca/"><strong>CI/CD 実践ガイド（1）：CI/CD とは？CI/CD を使って安定かつ効率的な開発チームを作るには？ツールの選び方は？</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/github-actions-self-hosted-runner-ci-cd-実践ガイドで自動化効率最大化-404bd5c70040/"><strong>CI/CD 実践ガイド（二）：GitHub Actions と self-hosted Runner の使い方と構築完全版</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm開発/github-actions-ios-app-ci-cd-自動化構築でビルドからデプロイまで最速実現-4b001d2e8440/"><strong>CI/CD 実践ガイド（三）：GitHub Actions を使ったアプリプロジェクトの CI と CD ワークフローの実装</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/"><strong>CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</strong></a></p>
  </li>
</ul>

<h4 id="-buy-me-a-beer-on-paypal"><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank">🍺 Buy me a beer on PayPal</a></h4>

<blockquote>
  <p><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank"><strong><em>本シリーズの記事は多くの時間と労力をかけて執筆しています。内容があなたのお役に立ち、チームの作業効率や製品品質の向上に貢献できたなら、ぜひコーヒーをご馳走してください。ご支援ありがとうございます！</em></strong></a></p>
</blockquote>

<p><img src="/assets/c008a9e8ceca/1*QJj54G9gOjtQS-rbHVT1SQ.webp" alt="Buy me a coffee" loading="lazy" decoding="async" width="700" height="700" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiIGhlaWdodD0iNzAwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/c008a9e8ceca/1*QJj54G9gOjtQS-rbHVT1SQ.png" /></p>

<p><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank">🍺 Buy me a beer on PayPal</a></p>

<p><em><a href="https://medium.com/zrealm-ios-dev/ci-cd-%E5%AF%A6%E6%88%B0%E6%8C%87%E5%8D%97-%E4%B8%80-ci-cd-%E6%98%AF%E4%BB%80%E9%BA%BC-%E5%A6%82%E4%BD%95%E9%80%8F%E9%81%8E-ci-cd-%E6%89%93%E9%80%A0%E7%A9%A9%E5%AE%9A%E9%AB%98%E6%95%88%E7%9A%84%E9%96%8B%E7%99%BC%E5%9C%98%E9%9A%8A-%E5%B7%A5%E5%85%B7%E9%81%B8%E6%93%87-c008a9e8ceca" target="_blank">Post</a> Mediumから変換： <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a> より。</em></p>]]></content>
  </entry><entry>
    <title type="html">XCodeアップグレードで必須チェック｜Releaseビルドの幽霊クラッシュ対策とロジック確認</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/xcode%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89%E3%81%A7%E5%BF%85%E9%A0%88%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF-release%E3%83%93%E3%83%AB%E3%83%89%E3%81%AE%E5%B9%BD%E9%9C%8A%E3%82%AF%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E5%AF%BE%E7%AD%96%E3%81%A8%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF%E7%A2%BA%E8%AA%8D-7508328d8b8d/" rel="alternate" type="text/html" title="XCodeアップグレードで必須チェック｜Releaseビルドの幽霊クラッシュ対策とロジック確認" />
    <published>2025-04-11T22:50:31+08:00</published>
    <updated>2025-04-11T22:50:31+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/7508328d8b8d</id><summary type="html">Releaseビルド時のみ発生する幽霊クラッシュやロジック問題に悩む開発者向けに、XCodeアップグレード時の効果的な検証手法を解説。Debugでは見えない不具合を早期発見し、安定したリリースを実現します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="iosアプリ開発" /><category term="xcode" /><category term="ビルド設定" /><category term="swift" /><category term="トラブルシューティング" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/7508328d8b8d/1*j4gTyeQwM-T7Ad3Fi29saQ.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/xcode%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89%E3%81%A7%E5%BF%85%E9%A0%88%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF-release%E3%83%93%E3%83%AB%E3%83%89%E3%81%AE%E5%B9%BD%E9%9C%8A%E3%82%AF%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E5%AF%BE%E7%AD%96%E3%81%A8%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF%E7%A2%BA%E8%AA%8D-7508328d8b8d/"><![CDATA[<h3 id="通霊ノート-xcode-アップデート時に必ずテストすべきこと">[通霊ノート] XCode アップデート時に必ずテストすべきこと…</h3>

<p>Build Configuration Release（リリース版、オンライン版）でのみ発生する原因不明のクラッシュやプログラムの論理問題に遭遇したが、Debugでは問題なく動作する。</p>

<p><img src="/assets/7508328d8b8d/1*j4gTyeQwM-T7Ad3Fi29saQ.webp" alt="Photo by Tommaso Pecchioli" loading="lazy" decoding="async" width="1400" height="933" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjkzMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/7508328d8b8d/1*j4gTyeQwM-T7Ad3Fi29saQ.jpeg" /></p>

<p>Photo by <a href="https://unsplash.com/@pecchio?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash" target="_blank">Tommaso Pecchioli</a></p>

<h3 id="tldr">TL;DR</h3>

<p>新しい XCode でプロジェクトをビルド・リリースする前に、単に Build &amp; Run でレイアウト崩れや異常がないか確認するだけでなく、<strong>以下もぜひ試してみてください</strong>：</p>

<ol>
  <li>
    <p>App ターゲットを選択する</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Build Settings</code> を選択する</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Optimization Level</code> を検索する</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Optimization Level</code> セクションを見つける</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Debug</code> 環境も <code class="language-plaintext highlighter-rouge">Release</code> と同じ値に設定する（例：<code class="language-plaintext highlighter-rouge">Fastest, Smallest [-Os]</code>）</p>
  </li>
  <li>
    <p>ビルドして実行し、異常がないか確認する</p>
  </li>
</ol>

<p><img src="/assets/7508328d8b8d/1*CUqYYFVjyXtxGkMlyd0Suw.webp" alt="" loading="lazy" decoding="async" width="832" height="401" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzIiIGhlaWdodD0iNDAxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/7508328d8b8d/1*CUqYYFVjyXtxGkMlyd0Suw.png" /></p>

<p>Testflight に直接アップロードしてテストしないのは、問題が発生した際にすぐにブレークポイントで原因を特定できるようにするためです。</p>

<blockquote>
  <p><em>もしユーザーからRelease（正式版、オンライン版）での問題（クラッシュや動作異常）が報告され、開発者がローカルで再現できない場合は、この設定を変更してローカルで試してみてください。</em></p>
</blockquote>

<h4 id="発生する可能性のある問題"><strong>発生する可能性のある問題</strong></h4>

<ul>
  <li>
    <p>コード上は正しいが、結果が異常になる</p>
  </li>
  <li>
    <p>コード上はクラッシュしないはずの箇所でクラッシュする</p>
  </li>
</ul>

<p>上記は Debug 環境の <code class="language-plaintext highlighter-rouge">Optimization Level = None [-O0]</code> では正常に動作し、<code class="language-plaintext highlighter-rouge">Optimization Level = Fastest, Smallest [-Os]</code>、つまり Release の設定値でのみ発生します。</p>

<h4 id="解決策">解決策</h4>

<p><strong>問題がある場合、多くは開発者のせいではありません</strong>；XCode の最適化バグが原因です。このバージョンの XCode でどうしてもビルドする必要がある場合は、自分でプログラムのワークアラウンドを調整し、新しいバージョンの XCode が出るのを待って正常かどうか確認してください。</p>

<blockquote>
  <p><strong><em>Release を直接 None に変更することは推奨しません。なぜなら、他の問題がさらに発生する可能性があるためです。</em></strong></p>
</blockquote>

<h3 id="お話の時間">お話の時間</h3>

<p>以下はここ数年の仕事で実際に遭遇した問題の事例です。</p>

<h4 id="ストーリー-1--アプリが評価依頼のポップアップを繰り返し表示する問題">ストーリー 1 — アプリが評価依頼のポップアップを繰り返し表示する問題</h4>

<p>私たちのアプリには以前、「アプリを開くとユーザーにアプリストアで評価をお願いする」機能がありました。ルールとしては3回表示したらそれ以上は表示しないようにしていました。しかし、多くのユーザーから毎回アプリを開くたびに表示され続けると報告があり、長期間ずっと何度も表示されてうるさいと不満が出ていました。</p>

<p>しかし、コードを見てもローカルでビルド＆実行し、シミュレーターや実機で試しても問題はありません。さまざまなエッジケースのシナリオも試しましたが再現できませんでした。UIテストを作成して何千回もパスを繰り返し、データをクリアして再試行しても問題は発生しませんでした。</p>

<p>あの時は夜中の3時過ぎまで悩み抜き、もうどうしようもなくて原因が全く思いつかず、目的もなくプロジェクト設定を見ていたら、ふと「Build SettingsをすべてReleaseの値に変えてみよう」と思いつきました。そこで初めて「Optimization Level = Fastest, Smallest [-Os]」で再現することがわかり、問題の箇所を特定できました。</p>

<p><strong>擬似コード</strong></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">invitedTimes</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1">// UserDefaultsから読み込み；更新後に再保存される</span>
<span class="kd">func</span> <span class="nf">requestAppStoreReviewIfNeeded</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">defer</span> <span class="p">{</span>
    <span class="n">invitedTimes</span> <span class="o">+=</span> <span class="mi">1</span> <span class="c1">// 今のところ動作するが、予期しない副作用があるかもしれない</span>
  <span class="p">}</span>

  <span class="k">guard</span> <span class="n">invitedTimes</span> <span class="o">&lt;</span> <span class="mi">3</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">return</span>
  <span class="p">}</span>
  
  <span class="k">self</span><span class="o">.</span><span class="nf">present</span><span class="p">(</span><span class="kt">AppStoreReviewRequestAlert</span><span class="p">())</span>
<span class="p">}</span>
</code></pre></div></div>

<blockquote>
  <p><em>このコードは前任者が開発したもので、コードを見る限り副作用はあるものの、ロジックに問題はなく、正常にコンパイルでき、実行も以前のバージョンでは問題ありませんでした。</em></p>
</blockquote>

<p>しかし、<code class="language-plaintext highlighter-rouge">Optimization Level = Fastest, Smallest [-Os]</code> に設定してブレークポイントで値をプリントすると異常が見つかりました。<code class="language-plaintext highlighter-rouge">invitedTimes += 1</code> の後、値が突然 <code class="language-plaintext highlighter-rouge">-24760045646797946</code> のような非常に大きな負の数に変わってしまい、そのためユーザーは毎回招待評価が表示されてしまいます。</p>

<p>当時はまずこの defer の書き方を直接変更し、それ以降は同様の問題のユーザー報告はありませんでした；その後、後続の XCode バージョンで同じ書き方と <code class="language-plaintext highlighter-rouge">Optimization Level = Fastest, Smallest [-Os]</code> でも正常に動作することを確認しました。</p>

<h4 id="ストーリー-2--あるページで直接クラッシュする">ストーリー 2 — あるページで直接クラッシュする</h4>

<p>Release (Testflight) 版の内測で、あるページ（WebView）をクリックすると必ずクラッシュする問題が発見されました。しかし、エンジニアがシミュレーターや実機で Build &amp; Run しても問題は発生しません。問題の原因を推測しては、ログを埋め込んだり修正したバージョンを Testflight にアップロードしてテストするという作業を繰り返し、とても時間がかかりました。その時、以前の恐怖がよみがえり、すぐに同僚にローカルの設定を <code class="language-plaintext highlighter-rouge">Optimization Level = Fastest, Smallest [-Os]</code> に変更してもらい、Build &amp; Run したところ、見事にローカルでクラッシュ問題を再現できました。</p>

<p>主な問題は、私たちが独自に特化した WebView の Obj-c コード内の変数が、<code class="language-plaintext highlighter-rouge">Optimization Level = Fastest, Smallest [-Os]</code> のときに null になることで、原因は不明です。とりあえずチェックを増やして保護しています。以前のバージョンでは正常だったため、新しい XCode がリリースされるのを待って、正常になるか試すしかありません。</p>

<h3 id="まとめ">まとめ</h3>

<p>実はこの罠に二度もはまっただけでなく、覚えていないものもあります。とにかく心得を残しておきます：</p>

<ol>
  <li>
    <p>新しい XCode バージョンで初めてリリースビルドを行う際は、必ずこれをテストしてください。</p>
  </li>
  <li>
    <p>問題は Release（正式版、オンライン版）でのみ発生します。基本的にこの問題について、設定を変更してローカルで再現できるか確認してください。</p>
  </li>
</ol>

<p><em><a href="https://medium.com/zrealm-ios-dev/%E9%80%9A%E9%9D%88%E7%AD%86%E8%A8%98-xcode-%E5%8D%87%E7%B4%9A%E6%99%82%E6%9C%80%E5%A5%BD%E6%B8%AC%E4%B8%80%E4%B8%8B%E7%9A%84%E4%BA%8B-7508328d8b8d" target="_blank">Post</a> は Medium から <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a> によって変換されました。</em></p>]]></content>
  </entry><entry>
    <title type="html">Mediumで1000フォロワー達成｜7年間の継続が生んだ信頼と影響力</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-dev/medium%E3%81%A71000%E3%83%95%E3%82%A9%E3%83%AD%E3%83%AF%E3%83%BC%E9%81%94%E6%88%90-7%E5%B9%B4%E9%96%93%E3%81%AE%E7%B6%99%E7%B6%9A%E3%81%8C%E7%94%9F%E3%82%93%E3%81%A0%E4%BF%A1%E9%A0%BC%E3%81%A8%E5%BD%B1%E9%9F%BF%E5%8A%9B-6fd11e9704f2/" rel="alternate" type="text/html" title="Mediumで1000フォロワー達成｜7年間の継続が生んだ信頼と影響力" />
    <published>2025-04-03T20:51:56+08:00</published>
    <updated>2025-04-03T20:51:56+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-dev/6fd11e9704f2</id><summary type="html">Mediumで7年間記事を継続し、1000フォロワーを獲得。読者の信頼を築き、影響力を高める具体的な運営法と成果を解説します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm Dev." /><category term="iosアプリ開発" /><category term="medium" /><category term="ライター" /><category term="フォロワー" /><category term="マイルストーン" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/6fd11e9704f2/1*OMahkVPjT8XjSrYpDdpu-g.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-dev/medium%E3%81%A71000%E3%83%95%E3%82%A9%E3%83%AD%E3%83%AF%E3%83%BC%E9%81%94%E6%88%90-7%E5%B9%B4%E9%96%93%E3%81%AE%E7%B6%99%E7%B6%9A%E3%81%8C%E7%94%9F%E3%82%93%E3%81%A0%E4%BF%A1%E9%A0%BC%E3%81%A8%E5%BD%B1%E9%9F%BF%E5%8A%9B-6fd11e9704f2/"><![CDATA[<h3 id="mediumでのフォロワー1000人のマイルストーン"><strong>Mediumでのフォロワー1,000人のマイルストーン</strong></h3>

<p>Mediumを7年間運営し、ついに1,000フォロワーのマイルストーンを達成！</p>

<p><img src="/assets/6fd11e9704f2/1*OMahkVPjT8XjSrYpDdpu-g.webp" alt="" loading="lazy" decoding="async" width="1200" height="556" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjU1NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6fd11e9704f2/1*OMahkVPjT8XjSrYpDdpu-g.png" /></p>

<blockquote>
  <p><em>英語版は下にあります。</em></p>
</blockquote>

<p>Mediumを7年間運営し、112本の記事、約13万字を積み重ね、800時間以上を費やし、ついに2025年4月2日に夢の目標である1,000フォロワーを達成しました。</p>

<p>話は長くなりますが、2018年からWeb開発からアプリ開発に転向しました。すべてが新鮮で、常に知識欲を持って自分で資料を調べながら学び、実践し、最終的に初めてのアプリを完成させてリリースしました。</p>

<p>完全に独学だったため、当時は多くの先輩たちが残したネット記事から大いに学びました。それがきっかけで、「教えることで学ぶ」という考えが生まれ、自分も良い循環を作りたいと思いました。</p>

<p>一開始は「共有の迷い」に陥り、内容が不十分ではないか、人に批判されるのではないか、読者の役に立たないのではないかと心配していました。<br />
しかし、考えを変えると、記事を書くことは種をまくようなもので、いつか似た問題を抱える開発者が私の記事から助けを得たり、さらに深く探求したりできるかもしれません。<br />
書いた内容が必ずしも見られるとは限りませんが、始めなければその素晴らしい可能性は起こりません。だからこそ書き続けることで、自分の能力も徐々に向上し、記事の内容も豊かになり、他人の役に立つチャンスが増えました。</p>

<p>その期間はちょうど時代の追い風に乗り、Appやソフトウェア開発が盛んに発展していました。日々学び続け、新機能を開発し、自分の経験を記事にして絶えず共有していました。同時に、新しい若い開発者も次々と参加していたため、投稿するたびに新しいフォロワーを獲得できました。</p>

<p>近年、産業の冷え込みやAIによるデジタルコンテンツ制作分野への影響、そしてMediumのSEOポリシーの変更により、新規フォロワーの増加が明らかに鈍化しました。「1K達成」を目指すことに対してはゆったりとした気持ちで臨むようになりましたが、初心を忘れず、共有の精神を持ち続け、記録を続けて同じような問題に直面する方々を助けています。<br />
また、日常生活や旅行記、レビュー、そして個人的な興味である自動化（RPA）に関する内容も共有し始めました。</p>

<p>1Kはただの通過点であり、今後ともどうぞよろしくお願いします。<br />
今後iOS開発の内容を続けるかどうかに関わらず、自分が経験した問題や学んだことを引き続き共有していきます。</p>

<p>心からこの7年間のご支援とご愛顧に感謝いたします！</p>

<p><strong>Harry,</strong>
<strong>2025/04/02.</strong></p>

<h4 id="英語">英語</h4>

<p>Mediumで7年間、112記事、約13万字を公開し、800時間以上を費やした結果、ついに2025年4月2日に待望の1,000フォロワーの節目を達成しました。</p>

<p>かなりの旅路でした。2018年、ウェブ開発からアプリ開発に方向転換したとき、すべてが新鮮でワクワクしていました。飽くなき好奇心で、常に情報を探し、実践しながら学び、ついに初めてのアプリを完成させて公開しました。</p>

<p>完全独学で学んだ私は、多くの経験豊富な開発者が共有するオンライン記事から大きな恩恵を受けました。これに触発され、「教えることで学ぶ」という考えのもと、自分でも執筆を始め、知識共有の良い循環を生み出したいと思いました。</p>

<p>最初は、共有することに疑念を抱いていました。内容が十分かどうか、批判されないか、さらには読者に本当の価値を提供できているかどうかを常に気にしていました。</p>

<p>最終的に、私は考え方を変えました。書くことは種をまくようなもので、いつか同じような問題に直面した開発者が私の記事から助けやインスピレーションを得るかもしれません。たとえ記事がすぐに読まれなくても、書き始めなければその可能性は生まれません。継続的に書き続けることで、徐々にスキルが向上し、内容が充実し、他の人に役立つ可能性が高まりました。</p>

<p>幸いにも、私はアプリやソフトウェア開発の急速な成長の波に乗ることができました。日々、学び、新機能を作り、経験を文章で共有しました。新しい開発者も次々と業界に参入し、記事ごとに新しいフォロワーが増えていきました。</p>

<p>近年、成長は著しく鈍化しました。これは業界の冷え込み、AIによるデジタルコンテンツ制作の変化、そしてMediumのSEOポリシーの変更が影響しています。徐々に1,000フォロワー達成へのプレッシャーを緩めましたが、共有への初期の情熱は失わず、同じような問題に直面する人々のために経験を記録し続けました。加えて、日常生活の話や旅行体験、製品レビュー、そして個人的な関心である自動化（RPA）に関するコンテンツも共有し始めました。</p>

<p>1,000人のフォロワー達成はあくまでひとつの節目に過ぎません。今後も変わらぬご支援をよろしくお願いいたします。iOS開発について書き続けるかどうかに関わらず、これからも直面した問題や得た知識を共有していきます。</p>

<p>この7年間、皆様のご支援とご同行に心より感謝申し上げます！</p>

<p><strong>Harry,</strong>
<strong>2025/04/02.</strong></p>

<p><em><a href="https://medium.com/zrealm-ios-dev/a-milestone-of-1-000-followers-on-medium-6fd11e9704f2" target="_blank">投稿</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>で変換。</em></p>]]></content>
  </entry><entry>
    <title type="html">Google Apps Script：Firebase App Distribution APIとの高速連携方法｜効率的なGoogle APIs統合</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/google-apps-script-firebase-app-distribution-api%E3%81%A8%E3%81%AE%E9%AB%98%E9%80%9F%E9%80%A3%E6%90%BA%E6%96%B9%E6%B3%95-%E5%8A%B9%E7%8E%87%E7%9A%84%E3%81%AAgoogle-apis%E7%B5%B1%E5%90%88-71400d408dc8/" rel="alternate" type="text/html" title="Google Apps Script：Firebase App Distribution APIとの高速連携方法｜効率的なGoogle APIs統合" />
    <published>2025-03-20T22:12:48+08:00</published>
    <updated>2025-07-10T21:00:24+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/71400d408dc8</id><summary type="html">Google Apps Scriptを活用し、Firebase App Distribution APIとの連携で開発効率を大幅向上。API統合の課題を解決し、スムーズなアプリ配布を実現する具体的手法を解説。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm ロボティック・プロセス・オートメーション" /><category term="iosアプリ開発" /><category term="firebaseアプリ配布" /><category term="google-apps-script" /><category term="google-api" /><category term="google-cloud-platform" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/71400d408dc8/1*O6JWKIIS5oxyrOS3q9NXRQ.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/google-apps-script-firebase-app-distribution-api%E3%81%A8%E3%81%AE%E9%AB%98%E9%80%9F%E9%80%A3%E6%90%BA%E6%96%B9%E6%B3%95-%E5%8A%B9%E7%8E%87%E7%9A%84%E3%81%AAgoogle-apis%E7%B5%B1%E5%90%88-71400d408dc8/"><![CDATA[<h3 id="google-apps-script-x-google-apis-の高速連携方法">Google Apps Script x Google APIs の高速連携方法</h3>

<p>Google Apps Script と Firebase App Distribution API の連携例として</p>

<h3 id="背景">背景</h3>

<p>以前、Google Apps Script を使った記事をいくつか書きました。その中で「<a href="/posts/zrealm-ロボティックプロセスオートメーション/google-apps-scriptで毎日データ報告をrpa自動化-効率化と正確性向上の秘訣-f6713ba3fee3/">Google Apps Script を使った毎日データレポートの RPA 自動化</a>」や「<a href="/posts/zrealm-ロボティック-プロセス-オートメーション/ga4自動数値通知ロボット-無料で作る3ステップ-google-apps-scriptとtelegram-bot連携-1e85b8df2348/">簡単 3 ステップ — 無料 GA4 自動データ通知ボットの作成</a>」では、Google Apps Script を使って Google Analytics と Google Sheet、Web App、Slack、Telegram を連携し、視覚化されたデータプラットフォームや通知サービスを素早く構築する方法を紹介しました。また、先月公開した記事「<a href="/posts/zrealm-dev/google-apps-script-web-appでgithub-action-ci-cdを効率化-フォーム連携で開発スピード向上-4cb4437818f2/">Google Apps Script Web App フォームで Github Action CI/CD を連携</a>」では、Google Apps Script Web App を使って Github API と連携し、CI/CD の GUI フォームサービスを実装しました。これらはすべて Google Apps Script の組み込みサービスや外部サービス（Slack、Github など）を直接連携しており、Google APIs を使う場面はありませんでした。</p>

<blockquote>
  <p><em>今回、CI/CD GUIフォームを最適化する際に、内テスト版をパッケージ化した後、Webアプリ上で直接Firebase Distributionのダウンロードリンクを表示したいと考えました。これを実現するにはGoogle APIsを連携する必要があります。</em></p>
</blockquote>

<h4 id="google-apps-script-x-firebase-app-distribution-api-v1">Google Apps Script x <a href="https://firebase.google.com/docs/reference/app-distribution/rest/" target="_blank">Firebase App Distribution API v1</a></h4>

<p><img src="/assets/71400d408dc8/1*O6JWKIIS5oxyrOS3q9NXRQ.webp" alt="" loading="lazy" decoding="async" width="771" height="740" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzEiIGhlaWdodD0iNzQwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/71400d408dc8/1*O6JWKIIS5oxyrOS3q9NXRQ.png" /></p>

<p>上図のように、従来の Google Analytics の組み込みサービス「AnalyticsData」とは異なり、Firebase App Distribution は組み込みの接続サービスを提供していないため、進階的な方法で接続する必要があります。</p>

<blockquote>
  <p><em>もともと Service Account を使って Access Token の生成や交換を自分で行う必要があると思っていた（少し面倒、以前の <a href="https://github.com/ZhgChgLi/ZReviewTender/blob/main/lib/GoogleAPI.rb" target="_blank">評価ロボットのオープンソースプロジェクト</a> を参照）が、<strong>実はそれほど面倒ではない。</strong></em></p>
</blockquote>

<h3 id="google-apps-script-x-google-apis-高度なサービス連携">Google Apps Script x Google APIs 高度なサービス連携</h3>

<h4 id="連携設定">連携設定</h4>

<p><strong>参考 <a href="https://developers.google.com/apps-script/guides/services/advanced?hl=zh-tw#requirements" target="_blank">公式ドキュメントの説明</a> に従い、以下の手順で高度な設定を行う必要があります：</strong></p>

<ol>
  <li>
    <p>スクリプトプロジェクトで <a href="https://developers.google.com/apps-script/guides/services/advanced?hl=zh-tw#enable_advanced_services" target="_blank">高度なサービスを有効にする</a> 必要があります。</p>
  </li>
  <li>
    <p>スクリプトで使用している <a href="https://developers.google.com/apps-script/guides/cloud-platform-projects?hl=zh-tw" target="_blank">Cloud Platform (GCP) プロジェクト</a> で、対応する進階サービスの API が有効になっていることを確認してください。</p>
  </li>
  <li>
    <p>もしスクリプトプロジェクトが2019年4月8日以降に作成された<a href="https://developers.google.com/apps-script/guides/cloud-platform-projects?hl=zh-tw#default_cloud_platform_projects" target="_blank">デフォルトのGCPプロジェクト</a>を使用している場合、進階サービスを有効にしてスクリプトプロジェクトを保存すると、APIは自動的に有効になります。まだ同意していない場合は、システムが<a href="https://cloud.google.com/terms/?hl=zh-tw" target="_blank">Google Cloud</a>および<a href="https://developers.google.com/terms?hl=zh-tw" target="_blank">Google API</a>の利用規約への同意を求めることがあります。</p>
  </li>
  <li>
    <p>もしスクリプトプロジェクトが<a href="https://developers.google.com/apps-script/guides/cloud-platform-projects?hl=zh-tw#standard_cloud_platform_projects" target="_blank">標準GCPプロジェクト</a>または古いデフォルトGCPプロジェクトを使用している場合、GCPプロジェクト内で<a href="https://developers.google.com/apps-script/guides/cloud-platform-projects?hl=zh-tw#enabling_an_api_in_a_standard_gcp_project" target="_blank">対応するAPIを手動で有効化</a>する必要があります。変更を行うにはGCPプロジェクトの編集権限が必要です。</p>
  </li>
</ol>

<h4 id="1-プロジェクト設定--関連付ける-google-cloud-platform-gcp-プロジェクトの設定">1. プロジェクト設定 — 関連付ける Google Cloud Platform (GCP) プロジェクトの設定</h4>

<p>Google Apps Script x Google APIs の高度なサービス連携では、GCP プロジェクトを作成し、それを Google Apps Script に関連付ける必要があります。Google APIs の使用権限は GCP の設定に従います。</p>

<p>したがって、GCP プロジェクト（Firebase の GCP プロジェクトでも可）を作成し、情報ページの「<code class="language-plaintext highlighter-rouge">プロジェクト番号</code>」を控え、この GCP プロジェクトで使用したい Google APIs が有効になっていること、そして現在ログインしているアカウントまたは使用したいアカウントがその GCP プロジェクトおよび Google APIs の権限を持っていることを確認してください。</p>

<p><img src="/assets/71400d408dc8/1*-BlhyGAEtkcDRrZ86H2BHg.webp" alt="" loading="lazy" decoding="async" width="1013" height="767" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDEzIiBoZWlnaHQ9Ijc2NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/71400d408dc8/1*-BlhyGAEtkcDRrZ86H2BHg.png" /></p>

<p><img src="/assets/71400d408dc8/1*fycqt1HNNO9qiu6RZ-WMlw.webp" alt="" loading="lazy" decoding="async" width="912" height="871" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTIiIGhlaWdodD0iODcxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/71400d408dc8/1*fycqt1HNNO9qiu6RZ-WMlw.png" /></p>

<blockquote>
  <p><strong><em>本記事では「 <a href="https://firebase.google.com/docs/reference/app-distribution/rest/" target="_blank">Firebase App Distribution API</a> 」を例にしています。</em></strong></p>
</blockquote>

<p><img src="/assets/71400d408dc8/1*T13M_lq7z-ui0_cLZtuHXg.webp" alt="" loading="lazy" decoding="async" width="869" height="830" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjkiIGhlaWdodD0iODMwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/71400d408dc8/1*T13M_lq7z-ui0_cLZtuHXg.png" /></p>

<p><code class="language-plaintext highlighter-rouge">プロジェクト番号</code> を Google Apps Script プロジェクト設定の下にある Google Cloud Platform プロジェクト番号に入力すると、現在ログインしているアカウントにその GCP プロジェクトの権限があれば、自動的にバインドされ設定が完了します。</p>

<h4 id="2-プロジェクト設定--エディタでappsscriptjsonマニフェストファイルを表示する">2. プロジェクト設定 — エディタで「appsscript.json」マニフェストファイルを表示する</h4>

<p><img src="/assets/71400d408dc8/1*YnhdxRSyr_CYB2CFnO_31Q.webp" alt="" loading="lazy" decoding="async" width="765" height="498" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjUiIGhlaWdodD0iNDk4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/71400d408dc8/1*YnhdxRSyr_CYB2CFnO_31Q.png" /></p>

<p>有効化後、エディタに戻るとファイル一覧に「<code class="language-plaintext highlighter-rouge">appsscript.json</code>」設定ファイルが表示されます：</p>

<p><img src="/assets/71400d408dc8/1*r8bheyYWj-TX7vFIum2GIQ.webp" alt="" loading="lazy" decoding="async" width="845" height="358" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NDUiIGhlaWdodD0iMzU4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/71400d408dc8/1*r8bheyYWj-TX7vFIum2GIQ.png" /></p>

<p>oauthScopes に以下の2つの記述が含まれていることを確認してください：</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"oauthScopes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"https://www.googleapis.com/auth/script.external_request"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"https://www.googleapis.com/auth/cloud-platform"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>もし保存されていない場合は、手動で貼り付けて保存してください。</p>

<h4 id="3接続コードの作成">3.接続コードの作成</h4>

<p>GCP プロジェクトを設定したら、連携コードの作成を開始できます。連携したい Google APIs の公式ドキュメントを直接参照してください。 <a href="https://firebase.google.com/docs/reference/app-distribution/rest/" target="_blank">Firebase App Distribution API v1</a> ：</p>

<p><img src="/assets/71400d408dc8/1*N0Zg4TEZQwTTLGCsaTdx8A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1193" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjExOTMiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/71400d408dc8/1*N0Zg4TEZQwTTLGCsaTdx8A.png" /></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">project</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">projects/[Firebase Project ID]/apps/[Firebase APP ID]</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// あなたの Project ID と App ID に置き換えてください</span>

<span class="kd">function</span> <span class="nf">debug</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">releases</span> <span class="o">=</span> <span class="nf">firebaseDistribution</span><span class="p">(</span><span class="dl">""</span><span class="p">);</span>

  <span class="nx">releases</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">release</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// リリースオブジェクト: https://firebase.google.com/docs/reference/app-distribution/rest/v1/projects.apps.releases?hl=zh-tw#Release</span>
    <span class="nx">Logger</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">release</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> ダウンロードURL: </span><span class="p">${</span><span class="nx">release</span><span class="p">.</span><span class="nx">testingUri</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
  <span class="p">});</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">firebaseDistribution</span><span class="p">(</span><span class="nx">releaseNote</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://firebaseappdistribution.googleapis.com/v1/</span><span class="dl">"</span><span class="o">+</span><span class="nx">project</span><span class="o">+</span><span class="dl">"</span><span class="s2">/releases?filter=releaseNotes.text%3D*</span><span class="dl">"</span><span class="o">+</span><span class="nx">releaseNote</span><span class="o">+</span><span class="dl">"</span><span class="s2">*</span><span class="dl">"</span><span class="p">;</span>
  <span class="c1">// フィルター: https://firebase.google.com/docs/reference/app-distribution/rest/v1/projects.apps.releases/list?hl=zh-tw</span>
  <span class="kd">const</span> <span class="nx">headers</span> <span class="o">=</span> <span class="p">{</span>
    <span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json; charset=UTF-8</span><span class="dl">"</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">Authorization</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Bearer </span><span class="dl">"</span> <span class="o">+</span> <span class="nx">ScriptApp</span><span class="p">.</span><span class="nf">getOAuthToken</span><span class="p">(),</span> <span class="c1">// 現在のアカウントのトークンを直接使用</span>
  <span class="p">};</span>
  
  <span class="kd">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
    <span class="dl">"</span><span class="s2">method</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">get</span><span class="dl">"</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">headers</span><span class="dl">"</span><span class="p">:</span> <span class="nx">headers</span>
  <span class="p">};</span>
  <span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">()).</span><span class="nx">releases</span><span class="p">;</span>
  
  <span class="k">if </span><span class="p">(</span><span class="nx">result</span> <span class="o">==</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">[];</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">[Firebase Project ID]</code> <strong>と <code class="language-plaintext highlighter-rouge">[Firebase APP ID]</code> は Firebase プロジェクトの設定で取得できます：</strong></p>

<p><img src="/assets/71400d408dc8/1*oql_FnmO7_ct8S3cOhP8lg.webp" alt="" loading="lazy" decoding="async" width="1200" height="1051" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwNTEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/71400d408dc8/1*oql_FnmO7_ct8S3cOhP8lg.png" /></p>

<p>コードを貼り付けた後、初回実行時に権限の承認が必要です。</p>

<p><img src="/assets/71400d408dc8/1*sW3ZjQA3dKS8HhAOCDsmBA.webp" alt="" loading="lazy" decoding="async" width="1125" height="647" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTI1IiBoZWlnaHQ9IjY0NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/71400d408dc8/1*sW3ZjQA3dKS8HhAOCDsmBA.png" /></p>

<p><img src="/assets/71400d408dc8/0*p-Zl0cob4mPrsNO6.webp" alt="" loading="lazy" decoding="async" width="700" height="557" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiIGhlaWdodD0iNTU3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/71400d408dc8/0*p-Zl0cob4mPrsNO6.png" /></p>

<ul>
  <li>
    <p>「権限の確認」をクリックしてください。</p>
  </li>
  <li>
    <p>実行するアカウントを選択します。通常は現在の Google Apps Script アカウントと同じです。</p>
  </li>
</ul>

<p><img src="/assets/71400d408dc8/0*m7enb51ZiNlWYeoT.webp" alt="" loading="lazy" decoding="async" width="700" height="557" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiIGhlaWdodD0iNTU3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/71400d408dc8/0*m7enb51ZiNlWYeoT.png" /></p>

<p><img src="/assets/71400d408dc8/0*SN-0owiePlKXIxLk.webp" alt="" loading="lazy" decoding="async" width="700" height="557" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiIGhlaWdodD0iNTU3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/71400d408dc8/0*SN-0owiePlKXIxLk.png" /></p>

<ul>
  <li>
    <p>「詳細設定」を展開 -&gt; 「XXX に移動」をクリック<br />
これは自分たち自身で使うアプリケーションなので、Google の認証は不要です。</p>
  </li>
  <li>
    <p>「許可する」をクリックしてください</p>
  </li>
</ul>

<blockquote>
  <p><em>上記の画面は必ず表示されるわけではなく、表示されない場合は無視してください。</em></p>
</blockquote>

<p><strong>許可後、次回から「デバッグ」や「実行」をクリックするだけでプログラムを実行できます：</strong></p>

<p>エラーが発生した場合：</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Exception</span><span class="o">:</span> <span class="n">https</span><span class="o">://</span><span class="n">firebaseappdistribution</span><span class="mf">.</span><span class="n">googleapis</span><span class="mf">.</span><span class="n">com</span> <span class="n">へのリクエストがコード403で失敗しました</span><span class="err">。</span><span class="n">サーバーの応答は省略されています</span><span class="o">:</span> <span class="p">{</span>
  <span class="s2">"error"</span><span class="o">:</span> <span class="p">{</span>
    <span class="s2">"code"</span><span class="o">:</span> <span class="mi">403</span><span class="p">,</span>
    <span class="s2">"message"</span><span class="o">:</span> <span class="s2">"リクエストに認証スコープが不足しています。"</span><span class="p">,</span>
    <span class="s2">"status"</span><span class="o">:</span> <span class="s2">"PERMISSION_DENIED"</span><span class="p">,</span>
    <span class="s2">"details"</span><span class="o">:...</span> <span class="p">(</span><span class="n">muteHttpExceptionsオプションを使用して完全な応答を確認してください</span><span class="p">)</span>
<span class="mf">...</span>
</code></pre></div></div>

<p>または</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Exception: UrlFetchApp.fetch を呼び出すための権限が不足しています。必要な権限: https://www.googleapis.com/auth/script.external_request
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">appsscript.json</code> の oauthScopes に以下の2つの記述が含まれていることを確認してください（手順2を参照）：</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"oauthScopes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"https://www.googleapis.com/auth/script.external_request"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"https://www.googleapis.com/auth/cloud-platform"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>エラーが発生した場合：</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Exception</span><span class="o">:</span> <span class="n">https</span><span class="o">://</span><span class="n">firebaseappdistribution</span><span class="mf">.</span><span class="n">googleapis</span><span class="mf">.</span><span class="n">com</span> <span class="n">へのリクエストが失敗し</span><span class="err">、</span><span class="n">コード401を返しました</span><span class="err">。</span><span class="n">省略されたサーバーレスポンス</span><span class="o">:</span> <span class="p">{</span>
  <span class="s2">"error"</span><span class="o">:</span> <span class="p">{</span>
    <span class="s2">"code"</span><span class="o">:</span> <span class="mi">401</span><span class="p">,</span>
    <span class="s2">"message"</span><span class="o">:</span> <span class="s2">"リクエストに無効な認証資格情報が含まれていました。OAuth 2アクセストークン、ログインクッキー、またはその他の認証情報が必要です...（muteHttpExceptionsオプションを使って完全なレスポンスを確認してください）
</span></code></pre></div></div>

<p>まだバインドされていない GCP プロジェクトを示しています（ステップ1を参照）。または、その GCP プロジェクトで使用したい Google APIs が有効になっていない、現在のアカウントに該当の GCP / Google APIs の使用権限や Firebase App の権限がない場合があります。設定を確認してください。</p>

<p>エラーが発生した場合：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Exception: https://firebaseappdistribution.googleapis.com へのリクエストが失敗し、コード 404 が返されました。サーバーの応答は省略されています：
</code></pre></div></div>

<p>または</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Exception</span><span class="o">:</span> <span class="n">https</span><span class="o">://</span><span class="n">firebaseappdistribution</span><span class="mf">.</span><span class="n">googleapis</span><span class="mf">.</span><span class="n">com</span> <span class="n">へのリクエストが失敗し</span><span class="err">、</span><span class="n">コード400が返されました</span><span class="err">。</span><span class="n">サーバーレスポンスの一部</span><span class="o">:</span> <span class="p">{</span>
  <span class="s2">"error"</span><span class="o">:</span> <span class="p">{</span>
    <span class="s2">"code"</span><span class="o">:</span> <span class="mi">400</span><span class="p">,</span>
    <span class="s2">"message"</span><span class="o">:</span> <span class="s2">"リクエストに無効な引数が含まれています。"</span><span class="p">,</span>
    <span class="s2">"status"</span><span class="o">:</span> <span class="s2">"INVALID_ARGUMENT"</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Google APIs のリクエストパスが正しいかどうか確認してください。</p>

<h4 id="連携成功">連携成功🎉🎉🎉</h4>

<p><img src="/assets/71400d408dc8/1*9OyoPtblFnGGIBRvlGw10Q.webp" alt="" loading="lazy" decoding="async" width="1026" height="474" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI2IiBoZWlnaHQ9IjQ3NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/71400d408dc8/1*9OyoPtblFnGGIBRvlGw10Q.png" /></p>

<p>短くて10行未満のコードでGoogle APIsをスムーズに連携できるのは本当に便利です。興味のある方は、比較として <a href="https://github.com/ZhgChgLi/ZReviewTender/blob/main/lib/GoogleAPI.rb" target="_blank">自作</a> のGoogle APIs連携時の認証トークン交換の手順を見てみると、その煩雑さがよく分かります。</p>

<h4 id="次のステップ">次のステップ：</h4>

<p>以前の記事「 <a href="/posts/zrealm-dev/google-apps-script-web-appでgithub-action-ci-cdを効率化-フォーム連携で開発スピード向上-4cb4437818f2/">使用 Google Apps Script Web App フォームで Github Action CI/CD ワークフローを連携</a> 」と組み合わせて、Firebase App Distribution のダウンロードリンクも Web App に表示し、メンバーが直接ダウンロードできるようにしました。</p>

<p><img src="/assets/71400d408dc8/1*nK3H3e3KgHEg8qz-KZ9ZGA.webp" alt="Demo Result" loading="lazy" decoding="async" width="797" height="716" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3OTciIGhlaWdodD0iNzE2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/71400d408dc8/1*nK3H3e3KgHEg8qz-KZ9ZGA.png" /></p>

<p>デモ結果</p>

<blockquote>
  <p><em>他の Google APIs も同様に接続可能です。</em></p>
</blockquote>

<h3 id="202507-更新">2025/07 更新:</h3>

<p>この機能は実際のパッケージングツールに統合されています。最新の記事事例もご参照ください：「 <a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/"><strong>CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</strong></a> 」</p>

<p><em><a href="https://medium.com/zrealm-robotic-process-automation/google-apps-script-x-google-apis-%E5%BF%AB%E9%80%9F%E4%B8%B2%E6%8E%A5%E6%95%B4%E5%90%88%E6%96%B9%E5%BC%8F-71400d408dc8" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>を使って変換しました。</em></p>]]></content>
  </entry><entry>
    <title type="html">Xcode 虛擬目錄問題｜混乱解消とXcodeGen・Tuist統合の開源ツール解決策</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-%E9%96%8B%E7%99%BA/xcode-%E8%99%9B%E6%93%AC%E7%9B%AE%E9%8C%84%E5%95%8F%E9%A1%8C-%E6%B7%B7%E4%B9%B1%E8%A7%A3%E6%B6%88%E3%81%A8xcodegen-tuist%E7%B5%B1%E5%90%88%E3%81%AE%E9%96%8B%E6%BA%90%E3%83%84%E3%83%BC%E3%83%AB%E8%A7%A3%E6%B1%BA%E7%AD%96-fd719053b376/" rel="alternate" type="text/html" title="Xcode 虛擬目錄問題｜混乱解消とXcodeGen・Tuist統合の開源ツール解決策" />
    <published>2025-03-02T20:21:31+08:00</published>
    <updated>2025-03-09T15:59:17+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-%E9%96%8B%E7%99%BA/fd719053b376</id><summary type="html">Xcodeの虚拟目录が引き起こす構造混乱を抱えるApple開発者向けに、XcodeGenやTuistとの統合を可能にする独自オープンソースツールで開発効率を劇的改善。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm 開発" /><category term="iosアプリ開発" /><category term="xcode" /><category term="swift" /><category term="tuist" /><category term="xcodegen" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/fd719053b376/1*fYk27y-BjMBjBFnwDfhxlw.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-%E9%96%8B%E7%99%BA/xcode-%E8%99%9B%E6%93%AC%E7%9B%AE%E9%8C%84%E5%95%8F%E9%A1%8C-%E6%B7%B7%E4%B9%B1%E8%A7%A3%E6%B6%88%E3%81%A8xcodegen-tuist%E7%B5%B1%E5%90%88%E3%81%AE%E9%96%8B%E6%BA%90%E3%83%84%E3%83%BC%E3%83%AB%E8%A7%A3%E6%B1%BA%E7%AD%96-fd719053b376/"><![CDATA[<h3 id="xcode-仮想フォルダの長年の問題と私のオープンソースツールによる解決策">XCode 仮想フォルダの長年の問題と私のオープンソースツールによる解決策</h3>

<p>Apple 開発者の職業病：Xcode 初期の仮想ディレクトリ使用により、ディレクトリ構造が混乱し、XcodeGen や Tuist などの最新ツールとの統合が困難に。</p>

<p><img src="/assets/fd719053b376/1*fYk27y-BjMBjBFnwDfhxlw.webp" alt="Photo by Saad Salim" loading="lazy" decoding="async" width="1200" height="832" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgzMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/fd719053b376/1*fYk27y-BjMBjBFnwDfhxlw.jpeg" /></p>

<p>Photo by <a href="https://unsplash.com/@saadx?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash" target="_blank">Saad Salim</a></p>

<h4 id="この投稿の英語版">この投稿の英語版：</h4>

<h4 id="xcodeの長年の仮想ディレクトリ問題と私のオープンソースツールによる解決策"><a href="/posts/zrealm-開発/xcode-虛擬目錄問題-混乱解消とxcodegen-tuist統合の開源ツール解決策-fd719053b376/">Xcodeの長年の仮想ディレクトリ問題と私のオープンソースツールによる解決策</a></h4>

<h3 id="背景">背景</h3>

<p>チームの規模やプロジェクトの成長に伴い、Xcode プロジェクトファイル（.xcodeproj）のサイズは徐々に大きくなります。プロジェクトの複雑さによっては十万行、さらには百万行に達することもあります。複数人が複数のブランチで並行開発を行うため、コンフリクトが発生するのは避けられません。<strong>XcodeProj ファイルのコンフリクトは Storyboard や .xib のコンフリクトと同様に解決が難しい</strong>です。これらも純粋な記述ファイルであるため、コンフリクト解決時に他人が追加したファイルを誤って削除したり、他人が削除したファイルの参照が戻ってきてしまうことがよくあります。</p>

<p>もう一つの問題は、モジュール化が進むにつれて、Xcode プロジェクトファイル（.xcodeproj）でのモジュールの作成や管理のプロセスが非常に使いにくいことです。モジュールに変更があっても、Xcode プロジェクトファイルの Diff でしか確認できず、チームがモジュール化に向かうのを妨げています。</p>

<blockquote>
  <p><em>もし衝突防止だけが目的であれば、pre-commit で簡単に <a href="https://github.com/chiahsien/sort-Xcode-project-file" target="_blank">File Sorting</a> を実行する方法があります。既存のスクリプトはGithubに多数あり、そのまま参考に設定可能です。</em></p>
</blockquote>

<h4 id="xcfolder"><a href="https://github.com/ZhgChgLi/XCFolder" target="_blank">XCFolder</a></h4>

<p><a href="https://github.com/ZhgChgLi/XCFolder" target="_blank"><img src="https://repository-images.githubusercontent.com/941421589/27855f06-b938-4458-a20f-3e317b4283b7" alt="" /></a></p>

<blockquote>
  <p><strong><em>要点を簡単に</em></strong> <em>、Xcodeの初期の仮想フォルダをXcode内のディレクトリ構造に沿った実際のフォルダに変換するツールを開発しました。</em></p>
</blockquote>

<p><img src="/assets/fd719053b376/1*eFNN12WDaAk6mr49OzmC_g.webp" alt="" loading="lazy" decoding="async" width="1400" height="484" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjQ4NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/fd719053b376/1*eFNN12WDaAk6mr49OzmC_g.jpeg" /></p>

<blockquote>
  <p><em>スクロールして続きを見る…</em></p>
</blockquote>

<h4 id="モダンな-xcode-プロジェクトファイル管理">モダンな Xcode プロジェクトファイル管理</h4>

<p>具体的な考え方は、複数人で開発する際に Storyboard や .xib の使用を推奨しないのと同じで、<strong>「Xcode プロジェクトファイル」を管理するために、メンテナンスしやすく、反復可能で、コードレビューができるインターフェースが必要</strong>です。現在、市場で主に使われている無料ツールは以下の2つです：</p>

<ul>
  <li>
    <p><a href="https://github.com/yonaskolb/XcodeGen" target="_blank">XCodeGen</a> ：老舗のツールで、YAMLでXcodeプロジェクトの内容を定義し、それをXcodeプロジェクトファイル（.xcodeproj）に変換します。<br />
YAMLで直接構造を定義できるため導入や学習コストが低いですが、モジュール化や依存管理機能は弱く、YAMLの動的設定も苦手です。</p>
  </li>
  <li>
    <p><a href="https://github.com/tuist/tuist" target="_blank">Tuist</a> ：近年登場した新しいツールで、Swift DSL を使って Xcode プロジェクトの内容を定義し、それを Xcode プロジェクトファイル (.xcodeproj) に変換します。<br />
より安定かつ柔軟で、モジュール化や依存関係管理機能が内蔵されていますが、学習と導入のハードルはやや高めです。</p>
  </li>
</ul>

<p><strong>どのツールを使っても、私たちのコアワークフローは以下のようになります：</strong></p>

<ol>
  <li>
    <p><strong>Xcode プロジェクト設定ファイルの作成（XcodeGen の <code class="language-plaintext highlighter-rouge">project.yaml</code> または Tuist の <code class="language-plaintext highlighter-rouge">Project.swift</code>）</strong></p>
  </li>
  <li>
    <p>XcodeGen または Tuist を開発者および CI/CD サーバー環境に導入する</p>
  </li>
  <li>
    <p><strong>XcodeGen または Tuist を使って設定ファイルから <code class="language-plaintext highlighter-rouge">.xcodeproj</code> Xcode プロジェクトファイルを生成する</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">/*.xcodeproj</code> ディレクトリファイルを <code class="language-plaintext highlighter-rouge">.gitignore</code> に追加する</p>
  </li>
  <li>
    <p>開発者のワークフローを調整し、ブランチを切り替える際に設定ファイルから <code class="language-plaintext highlighter-rouge">.xcodeproj</code> Xcode プロジェクトファイルを生成するために XcodeGen または Tuist を実行する必要がある</p>
  </li>
  <li>
    <p>CI/CD のプロセスを調整する際、設定ファイルから <code class="language-plaintext highlighter-rouge">.xcodeproj</code> Xcode プロジェクトファイルを生成するために XcodeGen または Tuist を実行する必要がある</p>
  </li>
  <li>
    <p>完了</p>
  </li>
</ol>

<p><code class="language-plaintext highlighter-rouge">.xcodeproj</code> の Xcode プロジェクトファイルは、XcodeGen または Tuist が YAML や Swift DSL の設定ファイルを元に生成します。同じ設定ファイルと同じツールのバージョンであれば、同じ結果が得られます。そのため、<code class="language-plaintext highlighter-rouge">.xcodeproj</code> ファイルを Git にコミットする必要はなくなり、将来的に <code class="language-plaintext highlighter-rouge">.xcodeproj</code> ファイルの競合が起こることを防げます。プロジェクト構成の変更やモジュールの追加・変更は、設定ファイルに戻って調整します。Yaml や Swift で書かれているので、簡単にイテレーションやコードレビューが可能です。</p>

<p><strong>Tuist Swift サンプル：</strong> <code class="language-plaintext highlighter-rouge">Project.swift</code></p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">import</span> <span class="nc">ProjectDescription</span>

<span class="n">let</span> <span class="n">project</span> <span class="o">=</span> <span class="nf">Project</span><span class="p">(</span>
    <span class="n">name</span><span class="o">:</span> <span class="s2">"MyApp"</span><span class="p">,</span>
    <span class="n">targets</span><span class="o">:</span> <span class="p">[</span>
        <span class="nf">Target</span><span class="p">(</span>
            <span class="n">name</span><span class="o">:</span> <span class="s2">"MyApp"</span><span class="p">,</span>
            <span class="n">platform</span><span class="o">:</span> <span class="mf">.</span><span class="n">iOS</span><span class="p">,</span>
            <span class="n">product</span><span class="o">:</span> <span class="mf">.</span><span class="n">app</span><span class="p">,</span>
            <span class="n">bundleId</span><span class="o">:</span> <span class="s2">"com.example.myapp"</span><span class="p">,</span>
            <span class="n">deploymentTarget</span><span class="o">:</span> <span class="mf">.</span><span class="nf">iOS</span><span class="p">(</span><span class="n">targetVersion</span><span class="o">:</span> <span class="s2">"15.0"</span><span class="p">,</span> <span class="n">devices</span><span class="o">:</span> <span class="p">[</span><span class="mf">.</span><span class="n">iphone</span><span class="p">,</span> <span class="mf">.</span><span class="n">ipad</span><span class="p">]),</span>
            <span class="n">infoPlist</span><span class="o">:</span> <span class="mf">.</span><span class="k">default</span><span class="p">,</span>
            <span class="n">sources</span><span class="o">:</span> <span class="p">[</span><span class="s2">"Sources/**"</span><span class="p">],</span>
            <span class="n">resources</span><span class="o">:</span> <span class="p">[</span><span class="s2">"Resources/**"</span><span class="p">],</span>
            <span class="n">dependencies</span><span class="o">:</span> <span class="p">[]</span>
        <span class="p">),</span>
        <span class="nf">Target</span><span class="p">(</span>
            <span class="n">name</span><span class="o">:</span> <span class="s2">"MyAppTests"</span><span class="p">,</span>
            <span class="n">platform</span><span class="o">:</span> <span class="mf">.</span><span class="n">iOS</span><span class="p">,</span>
            <span class="n">product</span><span class="o">:</span> <span class="mf">.</span><span class="n">unitTests</span><span class="p">,</span>
            <span class="n">bundleId</span><span class="o">:</span> <span class="s2">"com.example.myapp.tests"</span><span class="p">,</span>
            <span class="n">deploymentTarget</span><span class="o">:</span> <span class="mf">.</span><span class="nf">iOS</span><span class="p">(</span><span class="n">targetVersion</span><span class="o">:</span> <span class="s2">"15.0"</span><span class="p">,</span> <span class="n">devices</span><span class="o">:</span> <span class="p">[</span><span class="mf">.</span><span class="n">iphone</span><span class="p">,</span> <span class="mf">.</span><span class="n">ipad</span><span class="p">]),</span>
            <span class="n">infoPlist</span><span class="o">:</span> <span class="mf">.</span><span class="k">default</span><span class="p">,</span>
            <span class="n">sources</span><span class="o">:</span> <span class="p">[</span><span class="s2">"Tests/**"</span><span class="p">],</span>
            <span class="n">dependencies</span><span class="o">:</span> <span class="p">[</span><span class="mf">.</span><span class="nf">target</span><span class="p">(</span><span class="n">name</span><span class="o">:</span> <span class="s2">"MyApp"</span><span class="p">)]</span>
        <span class="p">)</span>
    <span class="p">]</span>
<span class="p">)</span>
</code></pre></div></div>

<p><strong>XCodeGen YAML の例：</strong> <code class="language-plaintext highlighter-rouge">project.yaml</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">MyApp</span>
<span class="na">options</span><span class="pi">:</span>
  <span class="na">bundleIdPrefix</span><span class="pi">:</span> <span class="s">com.example</span>
  <span class="na">deploymentTarget</span><span class="pi">:</span>
    <span class="na">iOS</span><span class="pi">:</span> <span class="s1">'</span><span class="s">15.0'</span>

<span class="na">targets</span><span class="pi">:</span>
  <span class="na">MyApp</span><span class="pi">:</span>
    <span class="na">type</span><span class="pi">:</span> <span class="s">application</span>
    <span class="na">platform</span><span class="pi">:</span> <span class="s">iOS</span>
    <span class="na">sources</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">Sources</span><span class="pi">]</span>
    <span class="na">resources</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">Resources</span><span class="pi">]</span>
    <span class="na">info</span><span class="pi">:</span>
      <span class="na">path</span><span class="pi">:</span> <span class="s">Info.plist</span>
      <span class="na">properties</span><span class="pi">:</span>
        <span class="na">UILaunchScreen</span><span class="pi">:</span> <span class="pi">{}</span>
    <span class="na">dependencies</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">framework</span><span class="pi">:</span> <span class="s">Vendor/SomeFramework.framework</span>
      <span class="pi">-</span> <span class="na">sdk</span><span class="pi">:</span> <span class="s">UIKit.framework</span>
      <span class="pi">-</span> <span class="na">package</span><span class="pi">:</span> <span class="s">Alamofire</span>

  <span class="na">MyAppTests</span><span class="pi">:</span>
    <span class="na">type</span><span class="pi">:</span> <span class="s">bundle.unit-test</span>
    <span class="na">platform</span><span class="pi">:</span> <span class="s">iOS</span>
    <span class="na">sources</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">Tests</span><span class="pi">]</span>
    <span class="na">dependencies</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">target</span><span class="pi">:</span> <span class="s">MyApp</span>
</code></pre></div></div>

<h4 id="ファイルディレクトリ構造">ファイルディレクトリ構造</h4>

<p>XCodeGen や Tuist はファイルの実際のディレクトリや位置に基づいて XCode プロジェクトファイル（.xcodeproj）のディレクトリ構造を生成します。<strong>実際のディレクトリが XCode プロジェクトのファイルディレクトリとなります</strong>。</p>

<p><img src="/assets/fd719053b376/1*rYgdRpEDwRiZoMLzM0WpSQ.webp" alt="" loading="lazy" decoding="async" width="1080" height="752" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDgwIiBoZWlnaHQ9Ijc1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/fd719053b376/1*rYgdRpEDwRiZoMLzM0WpSQ.png" /></p>

<p>したがって、ファイルの実際のディレクトリ位置が非常に重要であり、それを直接 Xcode プロジェクトのファイルディレクトリとして使用します。</p>

<p>これは現代の Xcode / Xcode プロジェクトにおいて、これら二つのディレクトリの位置が同じであることがごく普通のことですが、この問題こそ本記事で探究したいテーマです。</p>

<h3 id="初期の-xcode-における仮想ディレクトリの使用">初期の Xcode における仮想ディレクトリの使用</h3>

<p>初期の Xcode では、ファイルディレクトリ上で右クリックして「New Group」を選んでも実際のディレクトリは作成されません。ファイルはプロジェクトのルートディレクトリに置かれ、<code class="language-plaintext highlighter-rouge">.xcodeproj</code> の Xcode プロジェクトファイル内でファイル参照が行われます。そのため、ディレクトリは Xcode プロジェクトファイル内でのみ見え、実際には存在しません。</p>

<p><img src="/assets/fd719053b376/1*LPuedcbhL4OUJuLcO0xSPw.webp" alt="" loading="lazy" decoding="async" width="1168" height="746" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTY4IiBoZWlnaHQ9Ijc0NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/fd719053b376/1*LPuedcbhL4OUJuLcO0xSPw.png" /></p>

<p>時代の変化とともに、AppleはXcodeでこの奇妙な設計を徐々に廃止しました。後のXcodeでは「New Group with Folder」が追加され、デフォルトで実体フォルダを作成し、作成したくない場合は「New Group without Folder」を選択するようになりました。そして現在（Xcode 16）では「New Group」のみが残り、実体フォルダに基づいて自動的にXcodeプロジェクトのファイル構成が生成されます。</p>

<h4 id="仮想フォルダの問題">仮想フォルダの問題</h4>

<ul>
  <li>
    <p><strong>XcodeGen や Tuist が使えない理由は、どちらも実際のディレクトリ構造が必要で、Xcode プロジェクトファイル (.xcodeproj) を生成するためです。</strong></p>
  </li>
  <li>
    <p>Code Review の難しさ：Git の Web GUI ではディレクトリ構造が表示されず、ファイルがすべて平坦に並んで見えます。</p>
  </li>
  <li>
    <p>DevOps やサードパーティツールの統合が困難：例えば Sentry や Github はディレクトリごとに警告や自動アサインを設定できますが、ディレクトリがなくファイルだけだと設定できません。</p>
  </li>
  <li>
    <p>プロジェクトのディレクトリ構造が非常に複雑で、多くのファイルがルートディレクトリに平坦化されています。</p>
  </li>
</ul>

<blockquote>
  <p><em>古いプロジェクトで、初期に仮想フォルダの問題に気づかなかった場合、仮想フォルダ内に3,000以上のファイルがあることもあり、手動で移動すると終わる頃には辞職して売り子になっているかもしれません。これはまさに「<a href="https://x.com/1star_therapist" target="_blank"><strong>Apple開発者の職業病</strong></a> <strong>😔</strong>」と言えるでしょう。</em></p>
</blockquote>

<h3 id="xcode-プロジェクトの仮想ディレクトリから実ディレクトリへの変換">Xcode プロジェクトの仮想ディレクトリから実ディレクトリへの変換</h3>

<p>上述の理由から、Xcodeプロジェクトの仮想フォルダを実際のフォルダに変換することが急務です。そうしなければ、今後のプロジェクトのモダナイズや効率的な開発プロセスの推進ができません。</p>

<h4 id="-xcode-16-のフォルダに変換オプション">❌ Xcode 16 の「フォルダに変換」オプション</h4>

<p><img src="/assets/fd719053b376/1*FlhWWH5Qz4aLfB4hYVUgNA.webp" alt="XCode 16" loading="lazy" decoding="async" width="285" height="562" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyODUiIGhlaWdodD0iNTYyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/fd719053b376/1*FlhWWH5Qz4aLfB4hYVUgNA.png" /></p>

<p>XCode 16</p>

<p>昨年 Xcode 16 がリリースされたとき、このメニューの新しいオプションに注目していました。本来の期待は、仮想ディレクトリのファイルを自動で実際のディレクトリに変換してくれることでした。</p>

<p>しかし実際にはそうではなく、まずファイルをディレクトリに配置し、対応する実際の場所に置く必要があります。「Convert to folder」をクリックすると、新しいXcodeプロジェクトのディレクトリ設定方式「<code class="language-plaintext highlighter-rouge">PBXFileSystemSynchronizedRootGroup</code>」に変更されます。正直言って、<strong>変換自体には全く役に立たず、これは変換後に新しいディレクトリ設定方式にアップグレードできるというだけです。</strong></p>

<p>目次が作成されておらず、ファイルが正しく配置されていない場合、「Convert to folder」をクリックすると以下のエラーが表示されます：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>関連フォルダがありません
各グループには関連付けられたフォルダが必要です。以下のグループはフォルダと関連付けられていません：
• xxxx
ファイルインスペクタを使って各グループにフォルダを関連付けるか、内容を別のグループに移動した後にグループを削除してください。
</code></pre></div></div>

<h4 id="-オープンソースプロジェクト-venmo--synx">🫥 オープンソースプロジェクト <a href="https://github.com/venmo" target="_blank">venmo</a> / <a href="https://github.com/venmo/synx" target="_blank">synx</a></h4>

<p><a href="https://github.com/venmo/synx" target="_blank"><img src="https://opengraph.githubassets.com/c526221a2dff30443c7e38d86c4da063595d493a064d970245ff75a5593dc402/venmo/synx" alt="" /></a></p>

<p>Githubで長時間検索した結果、Rubyで書かれたこの仮想ディレクトリを実ディレクトリに変換するオープンソースツールしか見つかりませんでした。実際に動かしてみると効果はありましたが、約10年更新されておらず、多くのファイルは手動で対応・移動する必要があり、完全な変換はできなかったため断念しました。</p>

<blockquote>
  <p><em>しかし、このオープンソースプロジェクトに触発されて、自分で変換ツールを開発しようと思いました。</em></p>
</blockquote>

<h4 id="-私のオープンソースプロジェクト-zhgchgli--xcfolder">✅ 私のオープンソースプロジェクト <a href="https://github.com/ZhgChgLi" target="_blank">ZhgChgLi</a> / <a href="https://github.com/ZhgChgLi/XCFolder" target="_blank">XCFolder</a></h4>

<p><a href="https://github.com/ZhgChgLi/XCFolder" target="_blank"><img src="https://repository-images.githubusercontent.com/941421589/27855f06-b938-4458-a20f-3e317b4283b7" alt="" /></a></p>

<p>純粋な Swift で開発されたコマンドラインツールで、<a href="https://github.com/tuist/XcodeProj" target="_blank">XcodeProj</a> を使って <code class="language-plaintext highlighter-rouge">.xcodeproj</code> Xcode プロジェクトファイルを解析し、すべてのファイルの所属ディレクトリを取得し、ディレクトリを解析して仮想フォルダを実際のフォルダに変換し、ファイルを正しい場所に移動し、最後に <code class="language-plaintext highlighter-rouge">.xcodeproj</code> のディレクトリ設定を調整することで変換を完了します。</p>

<p><img src="/assets/fd719053b376/1*eFNN12WDaAk6mr49OzmC_g.webp" alt="" loading="lazy" decoding="async" width="1400" height="484" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjQ4NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/fd719053b376/1*eFNN12WDaAk6mr49OzmC_g.jpeg" /></p>

<p><strong>使用方法</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/ZhgChgLi/XCFolder.git
<span class="nb">cd</span> ./XCFolder
swift run XCFolder YOUR_XCODEPROJ_FILE.xcodeproj ./Configuration.yaml
</code></pre></div></div>

<p><strong>例えば：</strong></p>

<div class="language-objectivec highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">swift</span> <span class="n">run</span> <span class="n">XCFolder</span> <span class="p">.</span><span class="o">/</span><span class="n">TestProject</span><span class="o">/</span><span class="n">DCDeviceTest</span><span class="p">.</span><span class="n">xcodeproj</span> <span class="p">.</span><span class="o">/</span><span class="n">Configuration</span><span class="p">.</span><span class="n">yaml</span>
</code></pre></div></div>

<p><strong>CI/CD モード（</strong> <code class="language-plaintext highlighter-rouge">Non Interactive Mode</code> <strong>）：</strong></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">swift</span> <span class="n">run</span> <span class="kt">XCFolder</span> <span class="kt">YOUR_XCODEPROJ_FILE</span><span class="o">.</span><span class="n">xcodeproj</span> <span class="o">./</span><span class="kt">Configuration</span><span class="o">.</span><span class="n">yaml</span> <span class="o">--</span><span class="k">is</span><span class="o">-</span><span class="n">non</span><span class="o">-</span><span class="n">interactive</span><span class="o">-</span><span class="n">mode</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">Configuration.yaml</code> では実行したいパラメータを設定できます：</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 無視するディレクトリ、解析や変換は行わない</span>
ignorePaths:
- <span class="s2">"Pods"</span>
- <span class="s2">"Frameworks"</span>
- <span class="s2">"Products"</span>

<span class="c"># 無視するファイルタイプ、変換や移動はされない</span>
ignoreFileTypes:
- <span class="s2">"wrapper.framework"</span> <span class="c"># フレームワーク</span>
- <span class="s2">"wrapper.pb-project"</span> <span class="c"># Xcode プロジェクトファイル</span>
<span class="c">#- "wrapper.application" # アプリケーション</span>
<span class="c">#- "wrapper.cfbundle" # バンドル</span>
<span class="c">#- "wrapper.plug-in" # プラグイン</span>
<span class="c">#- "wrapper.xpc-service" # XPC サービス</span>
<span class="c">#- "wrapper.xctest" # XCTest バンドル</span>
<span class="c">#- "wrapper.app-extension" # アプリ拡張</span>

<span class="c"># ディレクトリを作成しファイルを移動するだけで、.xcodeproj のディレクトリ設定は変更しない</span>
moveFileOnly: <span class="nb">false</span>

<span class="c"># git mv コマンドを優先してファイルを移動する</span>
gitMove: <span class="nb">true</span>
</code></pre></div></div>

<p>⚠️ <strong>実行前の注意：</strong></p>

<ul>
  <li>
    <p>Git に未コミットの変更がないことを必ず確認してください。スクリプトが誤ってプロジェクトディレクトリを汚染するのを防ぐためです。<br />
（スクリプト実行時にチェックを行い、未コミットの変更がある場合は <code class="language-plaintext highlighter-rouge">❌ Error: There are uncommitted changes in the repository</code> エラーを投げます）</p>
  </li>
  <li>
    <p>デフォルトでは、<code class="language-plaintext highlighter-rouge">git mv</code> コマンドを優先してファイルを移動し、git のファイル履歴を完全に保持します。移動に失敗した場合や Git プロジェクトでない場合のみ、FileSystem Move を使用してファイルを移動します。</p>
  </li>
</ul>

<p><strong>実行完了を待つだけでOK：</strong></p>

<p><img src="/assets/fd719053b376/1*IL_-Ht1SH5ZCYogZHXULbQ.webp" alt="" loading="lazy" decoding="async" width="638" height="439" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MzgiIGhlaWdodD0iNDM5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/fd719053b376/1*IL_-Ht1SH5ZCYogZHXULbQ.png" /></p>

<p><img src="/assets/fd719053b376/1*8JNbDbR7pvZLhcoQLU_B6A.webp" alt="" loading="lazy" decoding="async" width="682" height="483" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2ODIiIGhlaWdodD0iNDgzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/fd719053b376/1*8JNbDbR7pvZLhcoQLU_B6A.png" /></p>

<p>⚠️ <strong>実行後の注意：</strong></p>

<ul>
  <li>
    <p>プロジェクトディレクトリに漏れている（赤色の）ファイルがないか確認してください。数が少なければ手動で修正可能ですが、多い場合は Configuration.yaml の ignorePaths、ignoreFileTypes の設定が正しいか確認してください。または <a href="https://github.com/ZhgChgLi/XCFolder/issues" target="_blank"><strong>Issueを作成</strong></a> して教えてください。</p>
  </li>
  <li>
    <p>Build Setting の関連パス（例：<code class="language-plaintext highlighter-rouge">LIBRARY_SEARCH_PATHS</code>）を手動で変更する必要があるか確認してください。</p>
  </li>
  <li>
    <p>クリーン＆ビルドを試してみてください。</p>
  </li>
  <li>
    <p><strong>もし現在の <code class="language-plaintext highlighter-rouge">.xcodeproj</code> Xcode プロジェクトファイルを管理するのが面倒なら、XcodeGen や Tuist を使ってディレクトリやファイルを直接再生成することもできます</strong></p>
  </li>
</ul>

<p><strong>スクリプトの修正：</strong></p>

<p>直接クリックで <code class="language-plaintext highlighter-rouge">./Package.swift</code> を開き、スクリプト内容を調整できます。</p>

<h4 id="その他の開発メモ">その他の開発メモ</h4>

<ul>
  <li>
    <p>得意先の <a href="https://github.com/tuist/XcodeProj" target="_blank">XcodeProj</a> を利用し、Swift オブジェクトで <code class="language-plaintext highlighter-rouge">.xcodeproj</code> <strong>Xcode プロジェクトファイルの内容</strong> に簡単にアクセスできます。</p>
  </li>
  <li>
    <p>同様に Clean Architecture を採用して開発しています。</p>
  </li>
  <li>
    <p>PBXGroup の設定で path がなく name のみの場合は仮想ディレクトリ、逆に path がある場合は実体ディレクトリとなります。</p>
  </li>
  <li>
    <p>Xcode 16 の新しいディレクトリ設定 <code class="language-plaintext highlighter-rouge">PBXFileSystemSynchronizedRootGroup</code> は、ルートディレクトリを宣言するだけで実体ディレクトリから自動的に解析され、各ディレクトリやファイルを <code class="language-plaintext highlighter-rouge">.xcodeproj</code> のプロジェクトファイル内に個別に宣言する必要がありません。</p>
  </li>
  <li>
    <p>直接 SPM（Package.swift）方式でコマンドラインツールを開発するのは本当に便利です！</p>
  </li>
</ul>

<p><em><a href="https://medium.com/zrealm-ios-dev/xcode-%E8%99%9B%E6%93%AC%E7%9B%AE%E9%8C%84%E8%90%AC%E5%B9%B4%E5%95%8F%E9%A1%8C%E6%8E%A2%E7%A9%B6%E8%88%87%E6%88%91%E7%9A%84%E9%96%8B%E6%BA%90%E5%B7%A5%E5%85%B7%E8%A7%A3%E6%B1%BA%E6%96%B9%E6%A1%88-fd719053b376" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>によって変換。</em></p>]]></content>
  </entry><entry>
    <title type="html">自動バックアップ Medium 記事を Github Pages｜Jekyllで効率的に管理する方法</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-dev/%E8%87%AA%E5%8B%95%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97-medium-%E8%A8%98%E4%BA%8B%E3%82%92-github-pages-jekyll%E3%81%A7%E5%8A%B9%E7%8E%87%E7%9A%84%E3%81%AB%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95-5bb7d3a4954f/" rel="alternate" type="text/html" title="自動バックアップ Medium 記事を Github Pages｜Jekyllで効率的に管理する方法" />
    <published>2025-01-18T23:12:33+08:00</published>
    <updated>2025-03-08T22:48:25+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-dev/5bb7d3a4954f</id><summary type="html">Mediumの記事を自動でGithub Pagesにバックアップし、Jekyllでサイトを構築・カスタマイズする手順を解説。個人ブログのデータ保護と継続的な更新を実現し、管理負担を大幅に軽減します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm Dev." /><category term="medium" /><category term="jekyll" /><category term="自動化" /><category term="iosアプリ開発" /><category term="github-pages" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/5bb7d3a4954f/1*oM79EdbsiBYiWnqb0mH8QQ.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-dev/%E8%87%AA%E5%8B%95%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97-medium-%E8%A8%98%E4%BA%8B%E3%82%92-github-pages-jekyll%E3%81%A7%E5%8A%B9%E7%8E%87%E7%9A%84%E3%81%AB%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95-5bb7d3a4954f/"><![CDATA[<h3 id="mediumの記事を自動でgithub-pagesjekyllにバックアップする話">Mediumの記事を自動でGithub Pages（Jekyll）にバックアップする話</h3>

<p>個人 Medium 記事のバックアップミラーサイト構築、運用、アップグレード、カスタマイズに関する記録</p>

<h4 id="はじめに">はじめに</h4>

<p>Mediumの運営は6年目に入り、記事数は昨年100本を突破しました。運営期間が長くなり記事が増えるにつれて、いつかMediumが突然閉鎖されたり、アカウントに異常が起きて全ての記事が消えてしまうのではないかと不安になります。内容の薄い記事もありますが、多くは技術構成や当時の問題解決の思考を記録したもので、私はよく過去の記事を見返して知識を復習しています。また、ここ数年は海外旅行の記録も始めており、これらは思い出でありアクセスも良好です。これらの内容が失われると二度と書き直せません。</p>

<h4 id="自作のバックアップツール開発">自作のバックアップツール開発</h4>

<p>私は普段 Medium プラットフォーム上で直接記事を書いており、自分のバックアップを持っていませんでした。そこで2022年の旧正月期間中に、Mediumの記事をダウンロードして Markdown ファイル（記事の画像や埋め込みコードなどを含む）に変換するツール <strong>— <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a> ：</strong> を開発しました。</p>

<p><a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank"><img src="https://repository-images.githubusercontent.com/493527574/9b5b7025-cc95-4e81-84a9-b38706093c27" alt="" /></a></p>

<p>そして、このツールでダウンロードした Markdown を <a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Jekyll (Chirpy Theme)</a> を使って静的バックアップミラーサイトとして Github Pages にデプロイしました — <a href="https://zhgchg.li/" target="_blank">https://zhgchg.li/</a></p>

<p><img src="/assets/5bb7d3a4954f/1*oM79EdbsiBYiWnqb0mH8QQ.webp" alt="&lt;https://zhgchg.li/&gt;" loading="lazy" decoding="async" width="1400" height="658" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjY1OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/5bb7d3a4954f/1*oM79EdbsiBYiWnqb0mH8QQ.png" /></p>

<p><a href="https://zhgchg.li/" target="_blank">https://zhgchg.li/</a></p>

<p>その時、この一連の流れを同じニーズを持つ友人がすぐに使えるように、Githubのテンプレートリポジトリとしてまとめました — <a href="https://github.com/ZhgChgLi/ZMediumToJekyll" target="_blank">ZMediumToJekyll</a>。その後（2022年以降）、<a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Jekyll (Chirpy Theme)</a> のバージョンや設定は更新していませんが、<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank"><strong>ZMediumToMarkdown</strong></a> は継続的にメンテナンスしており、時々フォーマット解析の誤りを見つけるとすぐに修正しています。現在は安定してきています。</p>

<p>当時使用していた <a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Jekyll (Chirpy Theme)</a> のバージョンは v5.x で、大きな問題はなく、必要な機能も揃っていました（例：固定表示、カテゴリー、タグ、カバー画像、コメントなど）。ただ、画面のスクロール時にスクロールできなくなることが頻繁にありましたが、数回スクロールすると正常に戻るという操作体験の欠点がありました。v6.x にアップグレードを試みましたが問題は解決せず、公式に報告しても返信がありませんでした。さらにバージョンアップに伴う競合も増えたため、最終的にアップグレードを完全に諦めました。</p>

<p>最近、<a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Jekyll (Chirpy Theme)</a> の問題を解決し、バージョンアップを行い、ついでに高速デプロイツール <a href="https://github.com/ZhgChgLi/ZMediumToJekyll" target="_blank">ZMediumToJekyll</a> を再最適化することを決心しました。</p>

<h3 id="新着medium-to-jekyll-starter-">新着！medium-to-jekyll-starter 🎉🎉</h3>

<h4 id="medium-to-jekyll-startergithubio"><a href="https://github.com/ZhgChgLi/medium-to-jekyll-starter.github.io" target="_blank">medium-to-jekyll-starter.github.io</a></h4>

<p><a href="https://github.com/ZhgChgLi/medium-to-jekyll-starter.github.io" target="_blank"><img src="https://repository-images.githubusercontent.com/918538745/779cd996-4dc3-4ee0-88b7-951b39fc4463" alt="" /></a></p>

<p>私は <a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank"><strong>Jekyll (Chirpy Theme)</strong></a> の最新版 v7.x に、自作の <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank"><strong>ZMediumToMarkdown</strong></a> Medium記事ダウンロード変換ツールを組み合わせて、新しい <a href="https://github.com/ZhgChgLi/medium-to-jekyll-starter.github.io" target="_blank">medium-to-jekyll-starter.github.io</a> Githubテンプレートリポジトリとして再構成しました。</p>

<p>皆さんはこのテンプレートリポジトリを使って、自分の Medium ミラーコンテンツバックアップサイトを素早く設定・構築できます。<strong>一度設定すれば永久に自動バックアップが続き、Github Pages 上で完全無料で公開可能</strong>です。</p>

<blockquote>
  <p><strong><em>手順を追った設定ガイドはこちらの記事をご参照ください： <a href="https://zhgchg.li/posts/medium-to-jekyll/" target="_blank">https://zhgchg.li/posts/medium-to-jekyll/</a></em></strong></p>
</blockquote>

<h4 id="成果">成果</h4>

<p><img src="/assets/5bb7d3a4954f/1*Nyg7Fg93sDUAIMZQfN5QTg.webp" alt="&lt;https://zhgchg.li/&gt;" loading="lazy" decoding="async" width="1200" height="852" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/5bb7d3a4954f/1*Nyg7Fg93sDUAIMZQfN5QTg.png" /></p>

<p><a href="https://zhgchg.li/" target="_blank">https://zhgchg.li/</a></p>

<blockquote>
  <p><strong>上記のすべての記事は、私の Medium から</strong>自動的に<em>*すべての内容をダウンロードし、Markdown 形式に変換して再アップロードしたものです。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>適当な記事の変換結果を比較例として添付：</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em><a href="https://shorturl.at/CG9ua" target="_blank">Medium 上の元の内容</a> / <a href="/posts/pinkoiエンジニアリング/design-patterns-socket-io-client封裝で直面した課題と実践的解決策-78507a8de6a5/">変換後の個人サイトでの結果</a></em></strong></p>
</blockquote>

<p>アップグレード後、スクロールが止まる問題は再発しませんでした。今回のアップグレードで、カスタマイズした動的コンテンツ（Mediumのフォロワー数表示）も追加しました。</p>

<h3 id="一部の技術記録">一部の技術記録</h3>

<p><a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Jekyll (Chirpy Theme)</a> を Github Pages にデプロイする設定方法は、主に公式の Start Repo を直接参照します：</p>

<p><a href="https://github.com/cotes2020/chirpy-starter/tree/main" target="_blank"><img src="https://opengraph.githubassets.com/e23e4502475ff31a4a9ea0acb4524983a049cf151ec9ef48fe0777bbc9d8edb1/cotes2020/chirpy-starter" alt="" /></a></p>

<blockquote>
  <p><em>先月もこのプロジェクトの方法を参考にして、新しいオープンソースプロジェクト — <a href="https://github.com/ZhgChgLi/linkyee" target="_blank">Linkyee</a> オープンソース版の Link Tree 個人リンクページを作成しました。</em></p>
</blockquote>

<p><img src="/assets/5bb7d3a4954f/1*OTotv1Nw-KnhsflSSiNgkg.webp" alt="&lt;https://link.zhgchg.li/&gt;" loading="lazy" decoding="async" width="1400" height="854" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijg1NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/5bb7d3a4954f/1*OTotv1Nw-KnhsflSSiNgkg.png" /></p>

<p><a href="https://link.zhgchg.li/" target="_blank">https://link.zhgchg.li/</a></p>

<h4 id="jekyll-カスタマイズ方法-1--htmlのオーバーライド">Jekyll カスタマイズ方法 (1) — HTMLのオーバーライド</h4>

<p><a href="https://jekyllrb.com/" target="_blank">Jekyll</a> は非常に強力な Ruby 製の静的サイトジェネレーターです。 <a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Jekyll (Chirpy Theme)</a> は Jekyll をベースにしたテーマの一つで、他のテーマと比較しても <a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Chirpy Theme</a> が最も質感が高く、操作体験が優れており、機能も充実しています。</p>

<p>Jekyll のページは継承性があり、<code class="language-plaintext highlighter-rouge">./_layouts</code> に <a href="https://github.com/cotes2020/jekyll-theme-chirpy/tree/master/_layouts" target="_blank">Jekyll と同じページファイル名</a> を追加すると、サイト生成時にエンジンがあなたのカスタムページ内容で元の内容を置き換えます。</p>

<p>例えば、各記事ページの末尾に一行のテキストを追加したい場合、元の投稿ページファイル（<a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/_layouts/post.html" target="_blank">post.html</a>）をコピーして、<code class="language-plaintext highlighter-rouge">./_layouts</code> ディレクトリに配置します：</p>

<p><img src="/assets/5bb7d3a4954f/1*oDykwzZ0P5o8GEw8lc3WPQ.webp" alt="" loading="lazy" decoding="async" width="133" height="38" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzMiIGhlaWdodD0iMzgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/5bb7d3a4954f/1*oDykwzZ0P5o8GEw8lc3WPQ.png" /></p>

<p>エディタで post.html を開き、該当箇所にテキストやカスタマイズを追加し、サイトを再デプロイするとカスタマイズ結果が反映されます。</p>

<p><img src="/assets/5bb7d3a4954f/1*7ni973_1JykXoj8le78v1A.webp" alt="" loading="lazy" decoding="async" width="303" height="124" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDMiIGhlaWdodD0iMTI0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/5bb7d3a4954f/1*7ni973_1JykXoj8le78v1A.png" /></p>

<p><code class="language-plaintext highlighter-rouge">./_include</code> ディレクトリを作成して、共有したいページの内容ファイルを入れることもできます：</p>

<p><img src="/assets/5bb7d3a4954f/1*rExx8jMcMfEQZ3LfvhwT2w.webp" alt="" loading="lazy" decoding="async" width="193" height="163" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOTMiIGhlaWdodD0iMTYzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/5bb7d3a4954f/1*rExx8jMcMfEQZ3LfvhwT2w.png" /></p>

<p>そして <code class="language-plaintext highlighter-rouge">post.html</code> の中で、直接 <code class="language-plaintext highlighter-rouge">{% include buymeacoffee.html %}</code> を使って先ほどのファイルの HTML 内容を再利用できます。</p>

<blockquote>
  <p><em>HTML Layout ファイルを上書きする利点は、100% カスタマイズ可能で、ページの内容やレイアウトを自由に調整できることです。欠点は、今回のアップグレード時に競合や予期しない結果が発生しやすく、カスタマイズ内容を再確認する必要があることです。</em></p>
</blockquote>

<h4 id="jekyll-カスタマイズ方法-2--プラグイン">Jekyll カスタマイズ方法 (2) — プラグイン</h4>

<p>第二の方法は、<a href="https://jekyllrb.com/docs/plugins/" target="_blank">Plugin</a> の中の <a href="https://jekyllrb.com/docs/plugins/hooks/#built-in-hook-owners-and-events" target="_blank">Hook</a> を使い、Jekyll が静的コンテンツを生成する段階で自分のカスタマイズした内容を注入する方法です。</p>

<p><img src="/assets/5bb7d3a4954f/1*JI-uJ8tIKnomJyQk9cVfyQ.webp" alt="" loading="lazy" decoding="async" width="651" height="423" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NTEiIGhlaWdodD0iNDIzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/5bb7d3a4954f/1*JI-uJ8tIKnomJyQk9cVfyQ.png" /></p>

<p><img src="/assets/5bb7d3a4954f/1*GrUJn6HXoBqYXUQMKrnqTA.webp" alt="組み込みフックの所有者とイベント" loading="lazy" decoding="async" width="647" height="285" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NDciIGhlaWdodD0iMjg1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/5bb7d3a4954f/1*GrUJn6HXoBqYXUQMKrnqTA.png" /></p>

<p>[Builtin Hookの所有者とイベント</p>

<p>Hook イベント](https://jekyllrb.com/docs/plugins/hooks/#built-in-hook-owners-and-events){:target=”_blank”} はたくさんありますが、ここでは私が使った <code class="language-plaintext highlighter-rouge">site:pre_render</code> と <code class="language-plaintext highlighter-rouge">post:pre_render</code> だけを載せます。</p>

<p>追加方法も非常に簡単で、<code class="language-plaintext highlighter-rouge">./_plugins</code> に Ruby ファイルを追加するだけです。</p>

<p><img src="/assets/5bb7d3a4954f/1*1QTCNuYJbJPlfJoMrc6v5g.webp" alt="posts-lastmod-hook.rb は元々あるプラグインです" loading="lazy" decoding="async" width="216" height="66" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMTYiIGhlaWdodD0iNjYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/5bb7d3a4954f/1*1QTCNuYJbJPlfJoMrc6v5g.png" /></p>

<p>posts-lastmod-hook.rb は元々あるプラグインです</p>

<p>いくつかの「疑似」動的コンテンツ機能が欲しいです。まず一つ目は、プロフィールの下に Medium のフォロワー数を表示し、ページのフッターにページ内容の最終更新日時を表示することです。</p>

<p><img src="/assets/5bb7d3a4954f/1*6JA9ONLP_A0eNL_q-5b6yg.webp" alt="" loading="lazy" decoding="async" width="1081" height="802" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDgxIiBoZWlnaHQ9IjgwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/5bb7d3a4954f/1*6JA9ONLP_A0eNL_q-5b6yg.png" /></p>

<p><code class="language-plaintext highlighter-rouge">./_plugins</code> フォルダに <code class="language-plaintext highlighter-rouge">zhgchgli-customize.rb</code> を作成しました：</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env ruby</span>
<span class="c1">#</span>
<span class="nb">require</span> <span class="s1">'net/http'</span>
<span class="nb">require</span> <span class="s1">'nokogiri'</span>
<span class="nb">require</span> <span class="s1">'uri'</span>
<span class="nb">require</span> <span class="s1">'date'</span>


<span class="k">def</span> <span class="nf">load_medium_followers</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">limit</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
  <span class="k">return</span> <span class="mi">0</span> <span class="k">if</span> <span class="n">limit</span><span class="p">.</span><span class="nf">zero?</span>

  <span class="n">uri</span> <span class="o">=</span> <span class="no">URI</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
  <span class="n">response</span> <span class="o">=</span> <span class="no">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="p">.</span><span class="nf">get_response</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span>
  <span class="k">case</span> <span class="n">response</span>
  <span class="k">when</span> <span class="no">Net</span><span class="o">::</span><span class="no">HTTPSuccess</span> <span class="k">then</span>
      <span class="n">document</span> <span class="o">=</span> <span class="no">Nokogiri</span><span class="o">::</span><span class="no">HTML</span><span class="p">(</span><span class="n">response</span><span class="p">.</span><span class="nf">body</span><span class="p">)</span>

      <span class="n">follower_count_element</span> <span class="o">=</span> <span class="n">document</span><span class="p">.</span><span class="nf">at</span><span class="p">(</span><span class="s1">'span.pw-follower-count &gt; a'</span><span class="p">)</span>
      <span class="n">follower_count</span> <span class="o">=</span> <span class="n">follower_count_element</span><span class="o">&amp;</span><span class="p">.</span><span class="nf">text</span><span class="o">&amp;</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)</span><span class="o">&amp;</span><span class="p">.</span><span class="nf">first</span>

      <span class="k">return</span> <span class="n">follower_count</span> <span class="p">\\</span><span class="o">|</span><span class="p">\\</span><span class="o">|</span> <span class="mi">0</span>
  <span class="k">when</span> <span class="no">Net</span><span class="o">::</span><span class="no">HTTPRedirection</span> <span class="k">then</span>
    <span class="n">location</span> <span class="o">=</span> <span class="n">response</span><span class="p">[</span><span class="s1">'location'</span><span class="p">]</span>
    <span class="k">return</span> <span class="n">load_medium_followers</span><span class="p">(</span><span class="n">location</span><span class="p">,</span> <span class="n">limit</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
  <span class="k">else</span>
      <span class="k">return</span> <span class="mi">0</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="vg">$medium_url</span> <span class="o">=</span> <span class="s2">"https://medium.com/@zhgchgli"</span>
<span class="c1"># _config.ymlで定義して、Jekyll::Hooks.register :site, :pre_render do \\|site\\| site.configで取得することも可能です</span>

<span class="vg">$medium_followers</span> <span class="o">=</span> <span class="n">load_medium_followers</span><span class="p">(</span><span class="vg">$medium_url</span><span class="p">)</span>

<span class="vg">$medium_followers</span> <span class="o">=</span> <span class="mi">1000</span> <span class="k">if</span> <span class="vg">$medium_followers</span> <span class="o">==</span> <span class="mi">0</span>
<span class="vg">$medium_followers</span> <span class="o">=</span> <span class="vg">$medium_followers</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">reverse</span><span class="p">.</span><span class="nf">scan</span><span class="p">(</span><span class="sr">/\d{1,3}/</span><span class="p">).</span><span class="nf">join</span><span class="p">(</span><span class="s1">','</span><span class="p">).</span><span class="nf">reverse</span>


<span class="no">Jekyll</span><span class="o">::</span><span class="no">Hooks</span><span class="p">.</span><span class="nf">register</span> <span class="ss">:site</span><span class="p">,</span> <span class="ss">:pre_render</span> <span class="k">do</span> <span class="p">\\</span><span class="o">|</span><span class="n">site</span><span class="p">\\</span><span class="o">|</span>

  <span class="n">tagline</span> <span class="o">=</span> <span class="n">site</span><span class="p">.</span><span class="nf">config</span><span class="p">[</span><span class="s1">'tagline'</span><span class="p">]</span>
  
  <span class="n">followMe</span> <span class="o">=</span> <span class="o">&lt;&lt;-</span><span class="no">HTML</span><span class="sh">
  &lt;a href="</span><span class="si">#{</span><span class="vg">$medium_url</span><span class="si">}</span><span class="sh">" target="_blank" style="display: block;text-align: center;font-style: normal;/* text-decoration: underline; */font-size: 1.2em;color: var(--heading-color);"&gt;</span><span class="si">#{</span><span class="vg">$medium_followers</span><span class="si">}</span><span class="sh">+ Followers on Medium&lt;/a&gt;
</span><span class="no">  HTML</span>

  <span class="n">site</span><span class="p">.</span><span class="nf">config</span><span class="p">[</span><span class="s1">'tagline'</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"</span><span class="si">#{</span><span class="n">followMe</span><span class="si">}</span><span class="s2">"</span><span class="p">;</span>
  <span class="n">site</span><span class="p">.</span><span class="nf">config</span><span class="p">[</span><span class="s1">'tagline'</span><span class="p">]</span> <span class="o">+=</span> <span class="n">tagline</span><span class="p">;</span>

  <span class="n">meta_data</span> <span class="o">=</span> <span class="n">site</span><span class="p">.</span><span class="nf">data</span><span class="p">.</span><span class="nf">dig</span><span class="p">(</span><span class="s1">'locales'</span><span class="p">,</span> <span class="s1">'en'</span><span class="p">,</span> <span class="s1">'meta'</span><span class="p">);</span>
  <span class="c1"># 英語のみの実装ですが、他の言語にも実装可能です。</span>

  <span class="k">if</span> <span class="n">meta_data</span>
    <span class="n">gmt_plus_8</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span><span class="p">.</span><span class="nf">getlocal</span><span class="p">(</span><span class="s2">"+08:00"</span><span class="p">)</span>
    <span class="n">formatted_time</span> <span class="o">=</span> <span class="n">gmt_plus_8</span><span class="p">.</span><span class="nf">strftime</span><span class="p">(</span><span class="s2">"%Y-%m-%d %H:%M:%S"</span><span class="p">)</span>
    <span class="n">site</span><span class="p">.</span><span class="nf">data</span><span class="p">[</span><span class="s1">'locales'</span><span class="p">][</span><span class="s1">'en'</span><span class="p">][</span><span class="s1">'meta'</span><span class="p">]</span> <span class="o">+=</span> <span class="s2">"&lt;br/&gt;Last updated: </span><span class="si">#{</span><span class="n">formatted_time</span><span class="si">}</span><span class="s2"> +08:00"</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<ul>
  <li>
    <p>原理は、サイトのレンダー前にフックを登録し、config の <code class="language-plaintext highlighter-rouge">tagline</code> 個人プロフィール下の紹介内容ブロックに Medium フォロワー数を表示する HTML を追加することです。</p>
  </li>
  <li>
    <p>Medium のフォロワー数は、毎回実行するたびに最新の数字を取得します。</p>
  </li>
  <li>
    <p>ページ下部の最終更新日時のロジックもほぼ同じで、サイト生成時に locales-&gt;en-&gt;meta に最終更新日時の文字列を追加しています。</p>
  </li>
  <li>
    <p>補足として、Hook が記事生成前の場合は Markdown を取得でき、Hook が記事生成後の場合は生成後の HTML を取得できます。</p>
  </li>
</ul>

<p>保存後、まずローカルで <code class="language-plaintext highlighter-rouge">bundle exec jekyll s</code> を実行して結果をテストできます：</p>

<p><img src="/assets/5bb7d3a4954f/1*T1idAZIWAJ2N9J054-PFSA.webp" alt="" loading="lazy" decoding="async" width="710" height="483" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MTAiIGhlaWdodD0iNDgzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/5bb7d3a4954f/1*T1idAZIWAJ2N9J054-PFSA.png" /></p>

<p>ブラウザで <code class="language-plaintext highlighter-rouge">127.0.0.1:4000</code> を開いて結果を確認します。</p>

<p><img src="/assets/5bb7d3a4954f/1*6JA9ONLP_A0eNL_q-5b6yg.webp" alt="" loading="lazy" decoding="async" width="1081" height="802" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDgxIiBoZWlnaHQ9IjgwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/5bb7d3a4954f/1*6JA9ONLP_A0eNL_q-5b6yg.png" /></p>

<p>最後に Github Pages リポジトリの Actions にスケジュールを追加して定期的にサイトを自動再生成するように設定し、完了しました：</p>

<p><img src="/assets/5bb7d3a4954f/1*2BFHmkhnytEwHTkNHwZsTg.webp" alt="" loading="lazy" decoding="async" width="1050" height="589" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDUwIiBoZWlnaHQ9IjU4OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/5bb7d3a4954f/1*2BFHmkhnytEwHTkNHwZsTg.png" /></p>

<p>在 <a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Jekyll (Chirpy Theme)</a> リポジトリの Actions で「 <code class="language-plaintext highlighter-rouge">pages-deploy.yml</code> 」を見つけ、<code class="language-plaintext highlighter-rouge">on:</code> に以下を追加します：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="na">schedule</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">cron</span><span class="pi">:</span> <span class="s2">"</span><span class="s">10</span><span class="nv"> </span><span class="s">1</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">*"</span> <span class="c1"># 毎日 UTC 01:10 に自動実行, https://crontab.guru</span>
</code></pre></div></div>

<blockquote>
  <p><em>Plugin の利点は、動的なコンテンツ効果（スケジュール更新）が可能で、サイト構造に影響を与えず、アップグレード時の衝突が起きにくいことです。欠点は、調整できる内容や表示位置に制限があることです。</em></p>
</blockquote>

<h4 id="jekyll-chirpy-theme-v7x-以降の-github-pages-デプロイの問題"><a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Jekyll (Chirpy Theme)</a> v7.x 以降の Github Pages デプロイの問題</h4>

<p>サイト構成の調整に加え、v.7.x のデプロイスクリプトも変更されました。従来の <a href="https://github.com/ZhgChgLi/medium-to-jekyll-starter.github.io/blob/main/tools/deploy.sh" target="_blank">deploy.sh</a> スクリプトは廃止され、直接 Github Actions のデプロイ手順を使用しています：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># build:</span>
<span class="c1"># ...</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">サイト成果物をアップロード</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/upload-pages-artifact@v3</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">path</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_site${{</span><span class="nv"> </span><span class="s">steps.pages.outputs.base_path</span><span class="nv"> </span><span class="s">}}"</span>

<span class="err">  </span><span class="na">deploy</span><span class="pi">:</span>
    <span class="na">environment</span><span class="pi">:</span>
      <span class="na">name</span><span class="pi">:</span> <span class="s">github-pages</span>
      <span class="na">url</span><span class="pi">:</span> <span class="s">${{ steps.deployment.outputs.page_url }}</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">needs</span><span class="pi">:</span> <span class="s">build</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">GitHub Pagesへデプロイ</span>
        <span class="na">id</span><span class="pi">:</span> <span class="s">deployment</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/deploy-pages@v4</span>
</code></pre></div></div>

<p>しかし、デプロイの過程で問題が発生しました：</p>

<p><code class="language-plaintext highlighter-rouge">Uploaded artifact size of 1737778940 bytes exceeds the allowed size of 1 GB</code> 私のサイトの内容が大きすぎて、Upload Artifact に失敗しました。しかし、以前のデプロイスクリプトは問題なかったので、元の <a href="https://github.com/ZhgChgLi/medium-to-jekyll-starter.github.io/blob/main/tools/deploy.sh" target="_blank">deploy.sh</a> と <a href="https://github.com/ZhgChgLi/zhgchgli.github.io/blob/main/.github/workflows/pages-deploy.yml" target="_blank">上の部分をコメントアウト</a> する方法に戻しました。</p>

<h4 id="github-pages-デプロイ時に-test-site-ステップがいつも通らない">Github Pages デプロイ時に Test Site ステップがいつも通らない</h4>

<p><a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank">Jekyll (Chirpy Theme)</a> のデプロイには、サイトの内容が正しいかどうかをテストするステップがあります。例えば、リンクが正常か、HTMLタグに欠落がないかなどを検証します。</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># build:</span>
<span class="c1"># ...</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">サイトのテスト</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">bundle exec htmlproofer _site \</span>
            <span class="s">\-\-disable-external \</span>
            <span class="s">\-\-no-enforce-https \</span>
            <span class="s">\-\-ignore-empty-alt \</span>
            <span class="s">\-\-ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/"</span>
</code></pre></div></div>

<p>私は自分で <code class="language-plaintext highlighter-rouge">--no-enforce-https</code> と <code class="language-plaintext highlighter-rouge">--ignore-empty-alt</code> を追加し、https と alt 属性のない HTML タグのチェックを無視しました。<strong>これら二つを無視して検査を通過させています（内容をすぐに変更できないため）</strong>。</p>

<p><a href="https://github.com/gjtorikian/html-proofer" target="_blank">htmlproofer</a> の CLI コマンドは公式ドキュメントに記載がなく、かなり探した結果、ある Issue の <a href="https://github.com/gjtorikian/html-proofer/issues/727#issuecomment-1334430268" target="_blank">Comment</a> でルールを見つけました：</p>

<p><img src="/assets/5bb7d3a4954f/1*kn6TE3wlIqIA8Nxe8OqTww.webp" alt="&lt;https://github.com/gjtorikian/html-proofer/issues/727#issuecomment-1334430268&gt;" loading="lazy" decoding="async" width="814" height="234" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MTQiIGhlaWdodD0iMjM0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/5bb7d3a4954f/1*kn6TE3wlIqIA8Nxe8OqTww.png" /></p>

<p><a href="https://github.com/gjtorikian/html-proofer/issues/727#issuecomment-1334430268" target="_blank">https://github.com/gjtorikian/html-proofer/issues/727#issuecomment-1334430268</a></p>

<h4 id="その他の記事補足">その他の記事補足</h4>

<ul>
  <li>
    <p><a href="/posts/zrealm-dev/github-pages-自訂網域設定で独自urlを実現-簡単手順ガイド-483af5d93297/">Github Pages カスタムドメインの使い方</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティック-プロセス-オートメーション/github-pagesでlinktree風連結ページを無料高速構築-完全カスタマイズ-独自ドメイン対応-70aeddb1fd9b/">Linkyee — GitHub Pages を使って個人用の LinkTree のようなリンクページを無料で簡単に作成</a></p>
  </li>
</ul>

<p><em><a href="https://medium.com/zrealm-ios-dev/%E8%87%AA%E5%8B%95%E5%82%99%E4%BB%BD-medium-%E6%96%87%E7%AB%A0%E5%88%B0-github-pages-jekyll-%E7%9A%84%E9%82%A3%E4%BA%9B%E4%BA%8B-5bb7d3a4954f" target="_blank">Post</a> は <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a> によって Medium から変換されました。</em></p>]]></content>
  </entry><entry>
    <title type="html">MediumからJekyllへ｜インストールと設定の完全ガイド</title>
    <link href="https://jp.zhgchg.li/posts/tools/medium%E3%81%8B%E3%82%89jekyll%E3%81%B8-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A8%E8%A8%AD%E5%AE%9A%E3%81%AE%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-medium-to-jekyll/" rel="alternate" type="text/html" title="MediumからJekyllへ｜インストールと設定の完全ガイド" />
    <published>2025-01-17T08:00:00+08:00</published>
    <updated>2025-01-17T08:00:00+08:00</updated>
    <id>https://jp.zhgchg.li/posts/tools/medium-to-jekyll</id><summary type="html">MediumからJekyllへの移行で悩む開発者向けに、インストールから設定までの手順を具体的に解説。効率的なブログ構築を実現し、サイト運用の自由度を大幅に向上させます。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="tools" /><category term="meidum" /><category term="github" /><category term="jekyll" /><category term="ruby" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/images/zmediumtomarkdown.jpeg" /><content type="html" xml:base="https://jp.zhgchg.li/posts/tools/medium%E3%81%8B%E3%82%89jekyll%E3%81%B8-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A8%E8%A8%AD%E5%AE%9A%E3%81%AE%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-medium-to-jekyll/"><![CDATA[<h1 id="開始">開始！</h1>

<p><a href="https://github.com/ZhgChgLi/medium-to-jekyll-starter.github.io"><img src="https://opengraph.githubassets.com/91a5dd913bf4d51e6b76fbcc7442c845023bdf93cb1a0ce1ac1c8a40d554f781/ZhgChgLi/medium-to-jekyll-starter.github.io" alt="" /></a></p>

<h2 id="1-テンプレートリポジトリへ移動---medium-to-jekyll-startergithubio">1. テンプレートリポジトリへ移動 -&gt; <a href="https://github.com/ZhgChgLi/medium-to-jekyll-starter.github.io">medium-to-jekyll-starter.github.io</a></h2>

<p><img src="/assets/medium-to-jekyll-starter/start-6.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<p>右上の「Use this template」→「Create a new repository」をクリックしてください</p>

<h2 id="2-新しいリポジトリを作成する">2. 新しいリポジトリを作成する</h2>

<p><img src="/assets/medium-to-jekyll-starter/start-2.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<ul>
  <li>
    <p>リポジトリ名：通常は <code class="language-plaintext highlighter-rouge">アカウント名または組織名.github.io</code> で、必ず <code class="language-plaintext highlighter-rouge">*.github.io</code> で終わる必要があります。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Public</code> リポジトリでなければ GitHub Pages は使用できません</p>
  </li>
</ul>

<h3 id="github-actions-の実行権限の調整">GitHub Actions の実行権限の調整</h3>

<p><img src="/assets/medium-to-jekyll-starter/github-action-permissions.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<ul>
  <li>作成後、GitHubのセキュリティ設定により、リポジトリの設定でGitHub Actionsの実行権限を有効にする必要があります。</li>
</ul>

<h2 id="3-必要に応じて-gh-pages-ブランチを作成する">3. 必要に応じて gh-pages ブランチを作成する</h2>

<p><img src="/assets/medium-to-jekyll-starter/start-3.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<ul>
  <li>
    <p>リポジトリのトップページで「<code class="language-plaintext highlighter-rouge">main</code>」ブランチのメニューをクリックし、「<code class="language-plaintext highlighter-rouge">gh-pages</code>」と入力します。存在しない場合は「Create branch <code class="language-plaintext highlighter-rouge">gh-pages</code> from <code class="language-plaintext highlighter-rouge">main</code>」を選択してください。</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">gh-pages</code> ブランチが既に存在する場合、または作成時に「Sorry, that branch already exists.」と表示された場合は、この手順をスキップしてください。</p>
  </li>
</ul>

<h2 id="4-enable-github-pagessettings---pages---build-and-deployment-に移動してください">4. Enable Github Pages，Settings -&gt; Pages -&gt; Build and deployment に移動してください</h2>

<p><img src="/assets/medium-to-jekyll-starter/start-4.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<ul>
  <li>「<code class="language-plaintext highlighter-rouge">gh-pages</code>」ブランチを選択し、「<code class="language-plaintext highlighter-rouge">Save</code>」をクリックして設定を保存してください</li>
</ul>

<h3 id="初回デプロイの実行">初回デプロイの実行</h3>

<p><img src="/assets/medium-to-jekyll-starter/first-deploy.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<ul>
  <li>Repo -&gt; 「Actions」-&gt;「Build and Deploy」-&gt;「Run workflow」-&gt;「Branch: main, Run workflow」</li>
</ul>

<h2 id="5-すべてのデプロイ作業が完了するまで待つ">5. すべてのデプロイ作業が完了するまで待つ</h2>

<p><img src="/assets/medium-to-jekyll-starter/start-5.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<ul>
  <li>
    <p>🟢 ページのビルドとデプロイメント</p>
  </li>
  <li>
    <p>🟢 ビルドとデプロイ</p>
  </li>
</ul>

<h2 id="6-サイトで結果を確認する">6. サイトで結果を確認する</h2>

<blockquote>
  <p>https://<code class="language-plaintext highlighter-rouge">アカウント名または組織名.github.io</code></p>
</blockquote>

<p><img src="/assets/medium-to-jekyll-starter/done.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<h3 id="トラブルシューティング">トラブルシューティング</h3>

<p>もしページに以下だけが表示されている場合：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>--- layout: home # インデックスページ ---
</code></pre></div></div>

<p>Github Pages の設定ミス、まだデプロイ中、または以前のページのキャッシュが原因の可能性があります。強制リロードやシークレットモードでブラウザを再起動して、もう一度ページを開いてください。</p>

<blockquote>
  <p>初回デプロイ成功！🎉🎉🎉続けて、Mediumアカウントの同期設定を行ってください。</p>
</blockquote>

<hr />

<h1 id="github-repo-github-actions-設定">Github Repo (Github Actions) 設定</h1>

<h2 id="1-所属の-github-リポジトリの-github-actions-ページに移動---zmediumtomarkdownをクリック---zmediumtomarkdownymlをクリック">1. 所属の Github リポジトリの Github Actions ページに移動 -&gt; 「ZMediumToMarkdown」をクリック -&gt; 「ZMediumToMarkdown.yml」をクリック</h2>

<p><img src="/assets/medium-to-jekyll-starter/github-1.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<blockquote>
  <p>https://github.com/{ORG}/{REPO_NAME}/blob/main/.github/workflows/ZMediumToMarkdown.yml</p>

  <h2 id="2-右側の編集ボタンをクリックする">2. 右側の「編集」ボタンをクリックする</h2>

  <p><img src="/assets/medium-to-jekyll-starter/github-2.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>
</blockquote>

<h2 id="3-medium記事の自動同期パラメータ設定">3. Medium記事の自動同期パラメータ設定</h2>

<p><img src="/assets/medium-to-jekyll-starter/github-3.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">ZMediumToMarkdown</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>
  <span class="na">schedule</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">cron</span><span class="pi">:</span> <span class="s2">"</span><span class="s">10</span><span class="nv"> </span><span class="s">1</span><span class="nv"> </span><span class="s">15</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">*"</span> <span class="c1"># UTCの01:10に実行されます。毎日。</span>
    <span class="c1"># 自動同期のスケジュール設定</span>
    <span class="c1"># ref: https://crontab.guru/</span>

<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">ZMediumToMarkdown</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">ZMediumToMarkdown 自動ボット</span>
      <span class="na">uses</span><span class="pi">:</span> <span class="s">ZhgChgLi/ZMediumToMarkdown@main</span>
      <span class="na">with</span><span class="pi">:</span>
        <span class="na">command</span><span class="pi">:</span> <span class="s2">"</span><span class="s">--cookie_uid</span><span class="nv"> </span><span class="s">${{</span><span class="nv"> </span><span class="s">secrets.MEDIUM_COOKIE_UID</span><span class="nv"> </span><span class="s">}}</span><span class="nv"> </span><span class="s">--cookie_sid</span><span class="nv"> </span><span class="s">${{</span><span class="nv"> </span><span class="s">secrets.MEDIUM_COOKIE_SID</span><span class="nv"> </span><span class="s">}}</span><span class="nv"> </span><span class="s">-j</span><span class="nv"> </span><span class="s">zhgchgli_test"</span>
        <span class="c1"># zhgchgli_test をあなたの Medium ユーザー名に置き換えてください</span>
        <span class="c1"># 例: https://medium.com/@zhgchgli -&gt; zhgchgli</span>
        <span class="c1"># ref: https://github.com/ZhgChgLi/ZMediumToMarkdown?tab=readme-ov-file#usage</span>
</code></pre></div></div>

<h3 id="アクセス権のある-medium-アカウントの-cookies-を提供してください">アクセス権のある Medium アカウントの Cookies を提供してください。</h3>

<ul>
  <li>
    <p>ペイウォールの記事がある場合は、必ず提供してください</p>
  </li>
  <li>
    <p>もし Medium 記事の同期が不完全（記事が欠落）である場合、それは同期時に Medium のファイアウォールにブロックされたことを意味します。その場合も提供してください</p>
  </li>
</ul>

<h4 id="medium-アカウントの-cookies-medium_cookie_uid-と-medium_cookie_sid-を取得する手順">Medium アカウントの Cookies MEDIUM_COOKIE_UID と MEDIUM_COOKIE_SID を取得する手順：</h4>

<p><img src="/assets/medium-to-jekyll-starter/github-4.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<ol>
  <li>
    <p>アクセス権のある Medium アカウントにログインし、<a href="https://medium.com/me/stats">Medium ダッシュボード</a>にアクセスします。</p>
  </li>
  <li>
    <p>空白部分で右クリックします。</p>
  </li>
  <li>
    <p>「Inspect」を選択します。</p>
  </li>
  <li>
    <p>Developer Console が表示されたら「Application」を選択します。</p>
  </li>
  <li>
    <p>「Cookies」-&gt;「https://medium.com」を選択します。</p>
  </li>
  <li>
    <p>下にスクロールして「<code class="language-plaintext highlighter-rouge">sid</code>」「<code class="language-plaintext highlighter-rouge">uid</code>」を探します。</p>
  </li>
  <li>
    <p>これら2つのフィールドの値をダブルクリックしてコピーします。</p>
  </li>
</ol>

<h4 id="medium-アカウントの-cookies-を-github-リポジトリの-secrets-に安全に保存する">Medium アカウントの Cookies を GitHub リポジトリの Secrets に安全に保存する</h4>

<h5 id="1-github-リポジトリの-settings---secrets-and-variables---actions---new-repository-secret-に移動する">1. Github リポジトリの Settings -&gt; Secrets and variables -&gt; Actions -&gt; New repository secret に移動する</h5>

<p><img src="/assets/medium-to-jekyll-starter/github-5.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<ul>
  <li>
    <p>名前: <code class="language-plaintext highlighter-rouge">MEDIUM_COOKIE_SID</code></p>
  </li>
  <li>
    <p>Secret: 前のステップでコピーした Medium アカウントの <code class="language-plaintext highlighter-rouge">sid</code> 値を貼り付けてください</p>
  </li>
</ul>

<blockquote>
  <p>https://github.com/{ORG}/{REPO_NAME}/settings/secrets/actions/new</p>

  <h5 id="2-新しいシークレット---medium_cookie_sid">2. 新しいシークレット - MEDIUM_COOKIE_SID</h5>

  <p><img src="/assets/medium-to-jekyll-starter/github-6.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>
</blockquote>

<h5 id="3-新しいシークレット---medium_cookie_uid">3. 新しいシークレット - MEDIUM_COOKIE_UID</h5>

<p><img src="/assets/medium-to-jekyll-starter/github-7.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<ul>
  <li>
    <p>名前: <code class="language-plaintext highlighter-rouge">MEDIUM_COOKIE_UID</code></p>
  </li>
  <li>
    <p>Secret: 前のステップでコピーした Medium アカウントの <code class="language-plaintext highlighter-rouge">uid</code> 値を貼り付けてください</p>
  </li>
</ul>

<h5 id="完了">完了</h5>

<p>アカウントが特別にログアウトされたり問題が発生しない限り、Cookies は無効になりません。</p>

<p>同期中に以下のメッセージが表示され、記事の同期が不完全な場合：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>この投稿はMediumの有料会員限定です。全文をダウンロードするには、有効なMediumメンバーのログインクッキーを提供する必要があります。
</code></pre></div></div>

<p>Cookiesが無効になっているため、上記の手順に従って再設定してください。</p>

<h2 id="4-初回手動同期repo---github-actions---zmediumtomarkdownをクリック---enable-workflowをクリック">4. 初回手動同期、Repo -&gt; Github Actions -&gt; 「ZMediumToMarkdown」をクリック -&gt; 「Enable workflow」をクリック</h2>

<p>初回実行時は、自分で手動同期を行い設定が正しいか確認できます。
<img src="/assets/medium-to-jekyll-starter/github-9.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<h2 id="5-同期記事とサイトのデプロイ完了を待つ">5. 同期記事とサイトのデプロイ完了を待つ</h2>

<p><img src="/assets/medium-to-jekyll-starter/github-10.png" alt="" loading="lazy" decoding="async" width="1200" height="800" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" /></p>

<p>以下の3つの Actions ワークフローが完了し、エラーがないことを確認してください：</p>

<ul>
  <li>
    <p>🟢 ZMediumToMarkdown</p>
  </li>
  <li>
    <p>🟢 ページのビルドとデプロイ</p>
  </li>
  <li>
    <p>🟢 ビルドとデプロイ</p>
  </li>
</ul>

<h2 id="6-ページをリロードして結果を確認しましょう楽しんでください">6. ページをリロードして結果を確認しましょう、楽しんでください！</h2>

<blockquote>
  <p>⚠️ ご注意ください！すべてのファイル変更は以下をトリガーします：</p>

  <ul>
    <li>
      <p>🟢 ページのビルドとデプロイメント</p>
    </li>
    <li>
      <p>🟢 ビルドとデプロイ</p>
    </li>
  </ul>

  <p>上記の2つのデプロイ作業が完了するまで待つ必要があり、その後にサイトの変更が反映されます。</p>
</blockquote>

<hr />

<h1 id="jekyll-サイト設定">Jekyll サイト設定</h1>

<h2 id="サイト基本設定">サイト基本設定</h2>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">./_config.yml</code></p>

    <p><strong>必ず調整してください</strong> <code class="language-plaintext highlighter-rouge">url:</code> をご自身の Github Pages のURLおよびその他のサイト情報に変更してください。</p>
  </li>
  <li>
    <p>共有機能の設定：<code class="language-plaintext highlighter-rouge">./_data/share.yml</code></p>
  </li>
  <li>
    <p>記事の著者情報を定義：<code class="language-plaintext highlighter-rouge">./_data/authors.yml</code></p>
  </li>
</ul>

<h2 id="左側-sidebar-設定">左側 Sidebar 設定</h2>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">./tabs</code></p>
  </li>
  <li>
    <p>フッターリンクボタン：<code class="language-plaintext highlighter-rouge">./_data/contact.yml</code></p>
  </li>
</ul>

<h2 id="サイトのフッターおよびその他のテキスト設定">サイトのフッターおよびその他のテキスト設定</h2>

<ul>
  <li><code class="language-plaintext highlighter-rouge">./locales/{Lang}.yml</code> のデフォルトは <code class="language-plaintext highlighter-rouge">/locales/en.yml</code> です</li>
</ul>

<h2 id="ローカルテスト">ローカルテスト</h2>

<ol>
  <li>
    <p>Ruby &gt;= 3.1 バージョンがインストールされて使用されていることを確認してください</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">cd ./</code></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">bundle install</code></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">bundle exec jekyll s</code><br />
（jekyll サーバーを起動）</p>
  </li>
  <li>
    <p><a href="http://127.0.0.1:4000/">http://127.0.0.1:4000/</a> にアクセスして結果を確認してください</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Ctrl-c</code> を押して停止します。</p>
  </li>
</ol>

<p>*サイトの基本設定ファイルを変更した場合は、再度実行する必要があります。</p>]]></content>
  </entry><entry>
    <title type="html">Google Apps Script Web AppでGithub Action CI/CDを効率化｜フォーム連携で開発スピード向上</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-dev/google-apps-script-web-app%E3%81%A7github-action-ci-cd%E3%82%92%E5%8A%B9%E7%8E%87%E5%8C%96-%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E9%80%A3%E6%90%BA%E3%81%A7%E9%96%8B%E7%99%BA%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E5%90%91%E4%B8%8A-4cb4437818f2/" rel="alternate" type="text/html" title="Google Apps Script Web AppでGithub Action CI/CDを効率化｜フォーム連携で開発スピード向上" />
    <published>2025-01-11T19:19:43+08:00</published>
    <updated>2025-12-17T23:45:42+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-dev/4cb4437818f2</id><summary type="html">Github Action WorkflowをGoogle Apps Script Web Appフォームと連携し、JiraやAsana、Slackなどのツールと統合。開発効率を最大35%向上させる具体的手法を解説します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm Dev." /><category term="iosアプリ開発" /><category term="google-apps-script" /><category term="github-actions" /><category term="slack" /><category term="github" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/4cb4437818f2/1*TiGXBQdPaCM6r2J1RHrgnA.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-dev/google-apps-script-web-app%E3%81%A7github-action-ci-cd%E3%82%92%E5%8A%B9%E7%8E%87%E5%8C%96-%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E9%80%A3%E6%90%BA%E3%81%A7%E9%96%8B%E7%99%BA%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E5%90%91%E4%B8%8A-4cb4437818f2/"><![CDATA[<h3 id="google-apps-script-web-app-フォームで-github-action-cicd-ワークフローを連携する方法">Google Apps Script Web App フォームで Github Action CI/CD ワークフローを連携する方法</h3>

<p>Github Action Workflow フォームの最適化と他のワークフローツール（Jira、Asana、Slackなど）との統合による開発効率の向上。</p>

<p><img src="/assets/4cb4437818f2/1*TiGXBQdPaCM6r2J1RHrgnA.webp" alt="左：元の Github Action ワークフローフォーム / 右： 最終成果 (GAS Web App フォーム)" loading="lazy" decoding="async" width="1222" height="692" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjIyIiBoZWlnaHQ9IjY5MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4cb4437818f2/1*TiGXBQdPaCM6r2J1RHrgnA.png" /></p>

<p>左：元の Github Action ワークフローフォーム / 右：<a href="https://script.google.com/macros/s/AKfycbw8SuK7lLLMdY86y3jxMJyzXqa5tdxJryRnteOnNi-lK--j6CmKYXj7UuU58DiS0NSVvA/exec" target="_blank">最終成果 (GAS Web App フォーム)</a></p>

<h3 id="202507-アップデート">2025/07 アップデート:</h3>

<p>この機能は実際のパッケージングツールに統合されています。最新の記事の事例をご参照ください：「<a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/"><strong>CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</strong></a>」</p>

<h3 id="背景">背景</h3>

<p>以前のチームは Github Action と Self-hosted Github Runner、さらに Slack を使って一連の CI/CD サービスを構築していました。全体的な効果は良好で、App 開発者にとっては構築とメンテナンスが比較的簡単でした。公式ドキュメントにある YAML パラメータに従って設定すれば自動的にトリガーされ、マシン面でも自分のマシンを Runner として簡単に利用できます。サービス自体は Github が管理しているため、バージョンアップなどを気にする必要がなく、Runner は Github からタスクを逆に受け取る仕組みなので、外部ネットワークのポートを特別に開ける必要もありません。</p>

<blockquote>
  <p><em>BitriseのようなGUIによるYAMLビルド方法と、Jenkinsのように自前のマシンを使う柔軟性や低コストのビルド環境の両方を享受でき、しかもJenkinsのようにサービス自体のメンテナンスに時間をかける必要がありません。</em></p>
</blockquote>

<blockquote>
  <p><strong>時間があれば、後で完全な App CI/CD と Github Action の構築過程についての記事を書きます。</strong></p>
</blockquote>

<h4 id="問題github-action-cicd-gui-フォーム">問題：Github Action CI/CD GUI フォーム</h4>

<p><img src="/assets/4cb4437818f2/1*55tCLFvuHtTyyvSLSv1vMA.webp" alt="Github Action GUI Form" loading="lazy" decoding="async" width="406" height="499" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MDYiIGhlaWdodD0iNDk5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*55tCLFvuHtTyyvSLSv1vMA.png" /></p>

<p>Github Action GUI フォーム</p>

<blockquote>
  <p><em>アプリ開発では、CDでテスト版や正式版のビルド、審査申請をトリガーする際に、外部パラメータの提供や環境・ブランチの選択が必要であり、それに応じてジョブが開始されます。</em></p>
</blockquote>

<p>Jenkins は自分でサービスを構築し、完全な Web GUI を持っていますが、Github Action にはそれがありません。唯一の Web GUI フォームは、Actions 内の「Run workflow」をクリックすると表示される簡易フォームで、ユーザーが外部パラメータを入力して CI/CD ワークフローをトリガーできます。</p>

<p>通常このCDパッケージを使用するユーザーは、必ずしもアプリ開発者本人ではなく、プロジェクトの権限を持っているとは限りません。例えば、QAは指定バージョンのパッケージを作成し、PMやバックエンドは開発中の特定バージョンをテスト用にパッケージ化する必要があります。Github Action Formはプロジェクトの権限がなければ使用できませんが、ユーザーはプロジェクト権限を持っているとは限らず、必ずしもエンジニアリングの背景があるわけでもありません。</p>

<p><strong>しかも、ここでは動的なフォームやデータ検証ができません。</strong></p>

<blockquote>
  <p><em>そのため、他のユーザーが操作できるように別のGUIサービスを用意する必要があります。</em></p>
</blockquote>

<h4 id="自作-slack-app-で解決">自作 Slack App で解決</h4>

<p>以前、チームには自動化を熱愛するメンバーがいて、Kotlin+Ktorで完全なSlackアプリのウェブサービスを構築しました。Slackのメッセージ、フォーム、コマンドなどの機能と連携し、CDパッケージングのリクエストを受け取り、転送し、Github Actionをトリガーして操作を実行し、その結果をSlackに返す仕組みです。</p>

<blockquote>
  <p><em>現在は開発リソースがなく、以前のように Kotlin+Ktor でサービスを構築していません</em></p>
</blockquote>

<h4 id="自分で作る-webiosmacos-アプリツール">自分で作る Web/iOS/macOS アプリツール</h4>

<p>現在のチームでは、もともと Jenkins を使用しており、基本的な Web インターフェースを用意して他のユーザーがログインして利用できるようにしています。また、非エンジニアのユーザーがより使いやすいように、Jenkins と連携したパラメータをラップする独自のアプリも開発しています。</p>

<blockquote>
  <p><strong><em>しかし、Github Action に移行した後、この一連の仕組みは廃止されました。</em></strong></p>
</blockquote>

<h4 id="-プライベート-github-pages">❌ プライベート Github Pages</h4>

<p>Github Pages を直接 CI/CD の Web GUI として構築することも可能かもしれませんが、現在は Github <a href="https://docs.github.com/en/enterprise-server@3.13/admin/configuration/configuring-your-enterprise/configuring-github-pages-for-your-enterprise#enabling-public-sites-for-github-pages" target="_blank">Enterprise</a> のみが Github Pages のアクセス権限を設定できます。他のプランでは、Private Repo であっても公開されてしまい、安全性は確保されません。</p>

<h4 id="-slack-appしかし-google-apps-script-で構築">❌ Slack App、しかし Google Apps Script で構築</h4>

<p>最初は以前のチーム経験に基づいて Slack App を CI/CD の GUI フォームサービスとして使用しようと考えましたが、現在は以前のように Kotlin+Ktor でサービスを構築するリソースがありません。そのため、まずは Function as a Service を使って迅速に構築を試みようと思いました。</p>

<p>Function as a Service にはいくつか種類がありますが、<a href="https://cloud.google.com/functions?hl=zh-tw" target="_blank">Cloud Functions</a> は自由度が高いです。しかし、組織のIT制限により、自由にパブリッククラウド関数を追加できず、料金の問題もあるため、やはりお馴染みの Google Apps Script に戻ってきました。</p>

<blockquote>
  <p><em>以前にGoogle Apps Scriptを使った自動化に関する記事をいくつか書いています。興味のある方はご覧ください：</em></p>
</blockquote>

<blockquote>
  <p><em>1. <strong>「 <a href="/posts/zrealm-ロボティックプロセスオートメーション/google-apps-scriptで毎日データ報告をrpa自動化-効率化と正確性向上の秘訣-f6713ba3fee3/">Google Apps Scriptを使った毎日データレポートのRPA自動化</a> 」</strong></em></p>
</blockquote>

<blockquote>
  <p><em>2. 「 <a href="https://medium.com/zrealm-robotic-process-automation/%E7%B0%A1%E5%96%AE-3-%E6%AD%A5%E9%A9%9F-%E6%89%93%E9%80%A0%E5%85%8D%E8%B2%BB-ga4-%E8%87%AA%E5%8B%95%E6%95%B8%E6%93%9A%E9%80%9A%E7%9F%A5%E6%A9%9F%E5%99%A8%E4%BA%BA-1e85b8df2348?source=collection_home---6------1-----------------------" target="_blank">簡単3ステップ — 無料GA4自動データ通知ロボットの作り方</a> 」</em></p>
</blockquote>

<blockquote>
  <p><em>3. 「 <a href="https://medium.com/zrealm-robotic-process-automation/crashlytics-google-analytics-%E8%87%AA%E5%8B%95%E6%9F%A5%E8%A9%A2-app-crash-free-users-rate-793cb8f89b72?source=collection_home---6------8-----------------------" target="_blank">Crashlytics + Google Analytics でアプリのクラッシュフリーユーザー率を自動取得</a> 」</em></p>
</blockquote>

<blockquote>
  <p><em>4. 「 <a href="https://medium.com/zrealm-robotic-process-automation/crashlytics-big-query-%E6%89%93%E9%80%A0%E6%9B%B4%E5%8D%B3%E6%99%82%E4%BE%BF%E5%88%A9%E7%9A%84-crash-%E8%BF%BD%E8%B9%A4%E5%B7%A5%E5%85%B7-e77b80cc6f89?source=collection_home---6------9-----------------------" target="_blank">Crashlytics + Big Queryでよりリアルタイムで便利なクラッシュ追跡ツールを作る</a> 」</em></p>
</blockquote>

<p>総じて、Google Apps Script は Google のもう一つの Function as a Service サービスで、主な特徴は無料であり、Google サービスと素早く連携できることです。しかし、制限も多く、例えば専用の言語しか使えない、実行時間が6分を超えられない、実行回数に上限がある、マルチスレッドをサポートしていないなどがあります。詳細は<a href="/posts/zrealm-ロボティックプロセスオートメーション/google-apps-scriptで毎日データ報告をrpa自動化-効率化と正確性向上の秘訣-f6713ba3fee3/">私の以前の記事</a>をご参照ください。</p>

<p>結論は不可能である理由は以下の通りです：</p>

<ul>
  <li>
    <p><a href="https://www.cloudflare.com/zh-tw/learning/serverless/what-is-serverless/" target="_blank">Function as a Service コールドスタート問題</a>。<br />
サービスが一定時間呼び出されないとスリープ状態になり、再度呼び出す際に起動に時間がかかります（3～≥5秒）。<strong>Slack App は API の応答時間に非常に厳しく、サービスは3秒以内に応答しなければ失敗とみなされます</strong>。そのため、Slack 側でエラーが発生し、イベントリスナーも見失われて重複送信が発生します。</p>
  </li>
  <li>
    <p><strong>Google Apps Script の doGet、doPost メソッドでは Headers を取得できません。</strong><br />
<strong>これにより、<a href="https://api.slack.com/authentication/verifying-requests-from-slack" target="_blank">公式のセキュリティ認証</a> を実行できず、<a href="https://api.slack.com/authentication/verifying-requests-from-slack" target="_blank">Slack のリトライ機能</a> を無効にできません。</strong></p>
  </li>
  <li>
    <p>Google Apps Script の単一スレッド問題。<br />
他のサービスと連携する場合、応答時間が3秒を超えると、Slack によって失敗と判断されます。</p>
  </li>
</ul>

<p>Slackのメッセージ、Block Kit、フォームを無理やり使って全体のフローをつなげましたが、上記の問題が頻発したため、最終的に断念しました。</p>

<blockquote>
  <p><strong><em>このシステムを作る場合は、やはり自分でサーバーやサービスを立てるべきで、Function as a Serviceは使わないでください！</em></strong></p>
</blockquote>

<h4 id="-slack-ワークフローフォーム">❌ Slack ワークフローフォーム</h4>

<p><img src="/assets/4cb4437818f2/1*KWBMdFswvl1KPdnTLStzhQ.webp" alt="" loading="lazy" decoding="async" width="1136" height="812" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTM2IiBoZWlnaHQ9IjgxMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/4cb4437818f2/1*KWBMdFswvl1KPdnTLStzhQ.png" /></p>

<p><img src="/assets/4cb4437818f2/1*hnDPyOfGCTW_yJf71krMnA.webp" alt="Slack Workflow Form (❌ カスタマイズ不可)" loading="lazy" decoding="async" width="519" height="458" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTkiIGhlaWdodD0iNDU4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*hnDPyOfGCTW_yJf71krMnA.png" /></p>

<p><a href="https://slack.com/intl/zh-tw/help/articles/24720245025555-%E8%87%AA%E5%8B%95%E5%8C%96%EF%BC%9A%E4%BD%BF%E7%94%A8%E7%B0%A1%E6%98%93%E8%A1%A8%E5%96%AE%E6%94%B6%E9%9B%86%E8%B3%87%E8%A8%8A" target="_blank">Slack Workflow Form</a> (❌ カスタマイズ不可)</p>

<p>また、Slack内蔵の自動化機能であるWorkflow Formも試しましたが、動的なフォーム内容（例：ブランチを取得してユーザーに選択させる）はできません。カスタマイズできるのは、データ送信の後続ステップのみです。</p>

<h3 id="-google-apps-script-web-app-gui-フォーム">✅ Google Apps Script Web App GUI フォーム</h3>

<p>山が動かなくても道は変わる、考え直してみると必ずしも Slack 統合にこだわる必要はないと思いました。Slack 統合は既存のチーム協業ツールに直接組み込めるので最適な方法ですが、リソースの制約から他の安定して使いやすい方法を模索せざるを得ませんでした。</p>

<blockquote>
  <p><em>改めて考えると、Google Apps Script 自体が Web アプリとしてデプロイ可能で、Web の doGet 時に GUI フォームを表示し、フォーム送信後に Github 連携の処理をトリガーできます。</em></p>
</blockquote>

<h4 id="最終成果-">最終成果 🎉</h4>

<p><img src="/assets/4cb4437818f2/1*pzW-Yki-4HbE2nYXC4q-Aw.webp" alt="Demo Web App Form" loading="lazy" decoding="async" width="653" height="672" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NTMiIGhlaWdodD0iNjcyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*pzW-Yki-4HbE2nYXC4q-Aw.png" /></p>

<p><a href="https://script.google.com/macros/s/AKfycbw8SuK7lLLMdY86y3jxMJyzXqa5tdxJryRnteOnNi-lK--j6CmKYXj7UuU58DiS0NSVvA/exec" target="_blank">Demo Web App Form</a></p>

<h4 id="ワークフロー"><strong>ワークフロー</strong></h4>

<p>私たちは Google Apps Script Web App を使って CI/CD フォームを構築し、Google Workspace アカウントに直接紐付けて、組織内のユーザーのみがアクセスできるように設定しています。現在ログインしているユーザーのメールアドレスを自動取得し、Github リポジトリの共有アカウント（または権限を持つアカウントの Personal Access Token）を使って Github API を呼び出し、ブランチ一覧を取得します。送信後は同じく API を使って Github Action をトリガーし、CI/CD の作業を開始します。</p>

<p>また、ユーザーのメールアドレスを使って Slack App 経由で Slack API を呼び出し、そのユーザーの Slack ID を取得し、Slack App を通じてメッセージを送信し、CI/CD タスクの実行状況を通知することもできます。</p>

<p>また、AsanaやJiraからチケットを取得し、選択後にGithub APIでブランチを検索してGithub Actionをトリガーし、最後にSlackでユーザーに通知するなど、他のツールや開発プロセスと統合することも可能です。</p>

<h4 id="step-1-google-apps-script-web-app-フォームの作成">Step 1. Google Apps Script Web App フォームの作成</h4>

<p><a href="https://script.google.com/home" target="_blank">Google Apps Script</a> にアクセスし、新しいプロジェクトを作成します。</p>

<p><img src="/assets/4cb4437818f2/1*T3if7Dfo0iJaa4N5VZyA1Q.webp" alt="" loading="lazy" decoding="async" width="928" height="370" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjgiIGhlaWdodD0iMzcwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*T3if7Dfo0iJaa4N5VZyA1Q.png" /></p>

<h4 id="step-2-フォーム内容とgasプログラムの作成">Step 2. フォーム内容とGASプログラムの作成</h4>

<p>HTMLやCSSを書くのが久しぶりで、自分でスタイルをデザインするのが面倒だったので、ChatGPTに少しデザインされたHTMLフォームのテンプレートを作ってもらいました。</p>

<p><img src="/assets/4cb4437818f2/1*IPv0afE5FAFj40F22s8Umg.webp" alt="" loading="lazy" decoding="async" width="1316" height="1139" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzE2IiBoZWlnaHQ9IjExMzkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/4cb4437818f2/1*IPv0afE5FAFj40F22s8Umg.png" /></p>

<p><img src="/assets/4cb4437818f2/1*F_HrfV_k16g_ojm1WIDDuA.webp" alt="" loading="lazy" decoding="async" width="978" height="608" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NzgiIGhlaWdodD0iNjA4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*F_HrfV_k16g_ojm1WIDDuA.png" /></p>

<p>GAS の左側ファイル一覧で「+」をクリックし、新しいファイル名に「 <code class="language-plaintext highlighter-rouge">Form.html</code> 」と入力して、GPT が生成した HTML フォームのテンプレート内容を貼り付けます。</p>

<p><code class="language-plaintext highlighter-rouge">Form.html：</code></p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!--HTML &amp; Style Gen by ChatGPT 4o--&gt;</span>
<span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;head&gt;</span>
  <span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">"UTF-8"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"viewport"</span> <span class="na">content=</span><span class="s">"width=device-width, initial-scale=1.0"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;title&gt;</span><span class="cp">&lt;?=title?&gt;</span><span class="nt">&lt;/title&gt;</span>
  <span class="nt">&lt;style&gt;</span>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 20px;
      background-color: #f7f7f7;
    }
    .form-container {
      max-width: 600px;
      margin: auto;
      padding: 20px;
      background-color: #ffffff;
      border-radius: 8px;
      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    }
    .form-container h2 {
      margin-bottom: 20px;
      color: #333333;
    }
    .form-group {
      margin-bottom: 15px;
    }
    .form-group label {
      display: block;
      margin-bottom: 5px;
      font-weight: bold;
      color: #555555;
    }
    .form-group input,
    .form-group select,
    .form-group textarea {
      width: 95%;
      padding: 10px;
      border: 1px solid #cccccc;
      border-radius: 4px;
      font-size: 16px;
    }
    .form-group input[type="radio"] {
      width: auto;
      margin-right: 10px;
    }
    .form-group .radio-label {
      display: inline-block;
      margin-right: 20px;
    }
    .form-group button {
      background-color: #4CAF50;
      color: white;
      padding: 10px 20px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
    }
    .form-group button:hover {
      background-color: #45a049;
    }
    .message {
      margin-top: 20px;
      padding: 15px;
      border-radius: 5px;
      font-size: 1em;
      text-align: center;
    }
    .message.success {
      background-color: #d4edda;
      color: #155724;
      border: 1px solid #c3e6cb;
    }
    .message.error {
      background-color: #f8d7da;
      color: #721c24;
      border: 1px solid #f5c6cb;
    }
    .hidden {
      display: none;
    }
  <span class="nt">&lt;/style&gt;</span>
<span class="nt">&lt;/head&gt;</span>
<span class="nt">&lt;body&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"form-container"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;h2&gt;</span><span class="cp">&lt;?=title?&gt;</span><span class="nt">&lt;/h2&gt;</span>
    <span class="nt">&lt;form</span> <span class="na">id=</span><span class="s">"myForm"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"message-block"</span> <span class="na">class=</span><span class="s">"hidden"</span><span class="nt">&gt;&lt;/div&gt;</span>
      <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"form-group"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">"email"</span><span class="nt">&gt;</span>メールアドレス：<span class="nt">&lt;/label&gt;</span>
        <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"email"</span> <span class="na">value=</span><span class="s">"&lt;?=email?&gt;"</span> <span class="err">readonly</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;/div&gt;</span>
      <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"form-group"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">"buildNumber"</span><span class="nt">&gt;</span>バージョン番号：<span class="nt">&lt;/label&gt;</span>
        <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"number"</span> <span class="na">value=</span><span class="s">"&lt;?=buildNumber?&gt;"</span><span class="nt">/&gt;</span>
      <span class="nt">&lt;/div&gt;</span>
      <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"form-group"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">"branch"</span><span class="nt">&gt;</span>レビュー中のPR：<span class="nt">&lt;/label&gt;</span>
        <span class="nt">&lt;select</span> <span class="na">id=</span><span class="s">"branch"</span> <span class="na">name=</span><span class="s">"branch"</span><span class="nt">&gt;</span>
          <span class="nt">&lt;option&gt;</span>選択してください<span class="nt">&lt;/option&gt;</span>
          <span class="cp">&lt;? pullRequests.forEach(pullRequest =&gt; { ?&gt;</span>
            <span class="nt">&lt;option</span> <span class="na">value=</span><span class="s">"&lt;?=pullRequest.head.ref?&gt;"</span><span class="nt">&gt;</span>[<span class="cp">&lt;?=pullRequest.state?&gt;</span>] <span class="cp">&lt;?=pullRequest.title?&gt;</span><span class="nt">&lt;/option&gt;</span>
          <span class="cp">&lt;? }); ?&gt;</span>
        <span class="nt">&lt;/select&gt;</span>
      <span class="nt">&lt;/div&gt;</span>
      <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"form-group"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">"message"</span><span class="nt">&gt;</span>更新内容：<span class="nt">&lt;/label&gt;</span>
        <span class="nt">&lt;textarea</span> <span class="na">id=</span><span class="s">"message"</span> <span class="na">name=</span><span class="s">"message"</span> <span class="na">rows=</span><span class="s">"4"</span> <span class="na">placeholder=</span><span class="s">"メッセージを入力してください"</span><span class="nt">&gt;&lt;/textarea&gt;</span>
      <span class="nt">&lt;/div&gt;</span>
      <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"form-group"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;button</span> <span class="na">type=</span><span class="s">"submit"</span><span class="nt">&gt;</span>送信<span class="nt">&lt;/button&gt;</span>
      <span class="nt">&lt;/div&gt;</span>
    <span class="nt">&lt;/form&gt;</span>
  <span class="nt">&lt;/div&gt;</span>
  <span class="nt">&lt;script&gt;</span>
    function displayMessage(ok, message) {
      const messageBlock = document.getElementById('message-block');
      messageBlock.className = ok ? 'message success' : 'message error';
      messageBlock.innerHTML = message;
      messageBlock.classList.remove('hidden');
    }
    
    document.getElementById("myForm").addEventListener("submit", function(e) {
      e.preventDefault();
      const formData = new FormData(this);
      const formObject = Object.fromEntries(formData);
      google.script.run.withSuccessHandler((response) =&gt; {
        displayMessage(response.ok, response.message);
      }).processForm(formObject);
    });
  <span class="nt">&lt;/script&gt;</span>
<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre></div></div>

<p>フォームの内容は必要に応じて自由に調整できます。</p>

<p><code class="language-plaintext highlighter-rouge">コード.gs：</code></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">doGet</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
  <span class="c1">// 左側ファイル Form.html に対応</span>
  <span class="kd">const</span> <span class="nx">htmlTemplate</span> <span class="o">=</span> <span class="nx">HtmlService</span><span class="p">.</span><span class="nf">createTemplateFromFile</span><span class="p">(</span><span class="dl">'</span><span class="s1">Form</span><span class="dl">'</span><span class="p">);</span>
  
  <span class="kd">const</span> <span class="nx">email</span> <span class="o">=</span> <span class="nx">Session</span><span class="p">.</span><span class="nf">getActiveUser</span><span class="p">().</span><span class="nf">getEmail</span><span class="p">();</span>
  <span class="c1">// ユーザーのメールアドレスを取得、実行権限：ウェブアプリをアクセスするユーザーに限定</span>
  
  <span class="kd">const</span> <span class="nx">title</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">App CD パッケージリクエストフォーム</span><span class="dl">"</span><span class="p">;</span>
  
  <span class="kd">const</span> <span class="nx">buildNumber</span> <span class="o">=</span> <span class="nf">genBuildNumber</span><span class="p">();</span>

  <span class="nx">htmlTemplate</span><span class="p">.</span><span class="nx">email</span> <span class="o">=</span> <span class="nx">email</span><span class="p">;</span>
  <span class="nx">htmlTemplate</span><span class="p">.</span><span class="nx">title</span> <span class="o">=</span> <span class="nx">title</span><span class="p">;</span>
  <span class="nx">htmlTemplate</span><span class="p">.</span><span class="nx">pullRequests</span> <span class="o">=</span> <span class="p">[];</span> <span class="c1">// 次に Github と連携予定...</span>
  <span class="nx">htmlTemplate</span><span class="p">.</span><span class="nx">buildNumber</span> <span class="o">=</span> <span class="nx">buildNumber</span><span class="p">;</span>

  <span class="kd">const</span> <span class="nx">html</span> <span class="o">=</span> <span class="nx">htmlTemplate</span><span class="p">.</span><span class="nf">evaluate</span><span class="p">();</span>
  <span class="nx">html</span><span class="p">.</span><span class="nf">setTitle</span><span class="p">(</span><span class="nx">title</span><span class="p">);</span>
  <span class="c1">//html.setWidth(600) // ページ幅を設定</span>

  <span class="k">return</span> <span class="nx">html</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">processForm</span><span class="p">(</span><span class="nx">object</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="p">{</span><span class="dl">"</span><span class="s2">ok</span><span class="dl">"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="dl">"</span><span class="s2">message</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">リクエスト送信成功！</span><span class="dl">"</span><span class="p">};</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">genBuildNumber</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">now</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Date</span><span class="p">();</span>
  <span class="kd">const</span> <span class="nx">formattedDate</span> <span class="o">=</span> <span class="nx">Utilities</span><span class="p">.</span><span class="nf">formatDate</span><span class="p">(</span><span class="nx">now</span><span class="p">,</span> <span class="dl">"</span><span class="s2">Asia/Taipei</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">yyyyMMddHHmmss</span><span class="dl">"</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">milliseconds</span> <span class="o">=</span> <span class="nx">now</span><span class="p">.</span><span class="nf">getMilliseconds</span><span class="p">().</span><span class="nf">toString</span><span class="p">().</span><span class="nf">padStart</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="dl">'</span><span class="s1">0</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// ミリ秒を3桁に揃える</span>
  <span class="k">return</span> <span class="s2">`</span><span class="p">${</span><span class="nx">formattedDate</span><span class="p">}${</span><span class="nx">milliseconds</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span> 
<span class="p">}</span>
</code></pre></div></div>

<p>このステップでは、まずフォームのGUIを完成させ、次にGithub APIを連携してPRブランチのリストを取得します。</p>

<p><img src="/assets/4cb4437818f2/1*RN9ftVBdgCA-IL8ra9jvTg.webp" alt="" loading="lazy" decoding="async" width="509" height="324" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MDkiIGhlaWdodD0iMzI0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*RN9ftVBdgCA-IL8ra9jvTg.png" /></p>

<h4 id="step-2-google-apps-script-web-app-フォームのデプロイ">Step 2. Google Apps Script Web App フォームのデプロイ</h4>

<p>まずは先ほどの内容を一度デプロイして、結果を確認しましょう。</p>

<p>GAS の右上で「デプロイ」-&gt; 「新しいデプロイ」-&gt;「ウェブアプリ」を選択します：</p>

<p><img src="/assets/4cb4437818f2/1*ouVO18FtOcX8vdeGCEtwCw.webp" alt="" loading="lazy" decoding="async" width="330" height="215" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMzAiIGhlaWdodD0iMjE1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*ouVO18FtOcX8vdeGCEtwCw.png" /></p>

<p><img src="/assets/4cb4437818f2/1*4BuEtIA4H_-Q9WALonYxYg.webp" alt="" loading="lazy" decoding="async" width="396" height="302" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzOTYiIGhlaWdodD0iMzAyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*4BuEtIA4H_-Q9WALonYxYg.png" /></p>

<p><img src="/assets/4cb4437818f2/1*JagpVPTGD-W0lhIJ5nrRew.webp" alt="" loading="lazy" decoding="async" width="762" height="599" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjIiIGhlaWdodD0iNTk5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*JagpVPTGD-W0lhIJ5nrRew.png" /></p>

<p>実行権限とアクセス可能なユーザーはそれぞれ以下のように設定できます：</p>

<p><strong>実行ユーザー：</strong></p>

<ul>
  <li>
    <p>私は「すべてあなたのアカウント権限でスクリプトを実行します。」</p>
  </li>
  <li>
    <p>ウェブアプリの利用者は、現在ログインしている Google アカウントのユーザー権限でスクリプトを実行します。</p>
  </li>
</ul>

<p><strong>誰がアクセスできますか：</strong></p>

<ul>
  <li>
    <p>私だけです</p>
  </li>
  <li>
    <p><strong>XXX 同じ組織内の全ユーザー</strong> <code class="language-plaintext highlighter-rouge">同じ組織でログインしているGoogleアカウントのユーザーのみアクセス可能。</code></p>
  </li>
  <li>
    <p>ログインしているすべての Google アカウントのユーザー <code class="language-plaintext highlighter-rouge">ログインしているすべてのGoogleアカウントユーザーがアクセス可能。</code></p>
  </li>
  <li>
    <p>すべての人が <code class="language-plaintext highlighter-rouge">Googleアカウントにログインせず、誰でも公開アクセス可能。</code></p>
  </li>
</ul>

<blockquote>
  <p><em>「誰がアクセスできるか：XXX 同じ組織内のすべてのユーザー」＋「実行者：ウェブアプリにアクセスするユーザー」を選択することで、<strong>組織アカウントを持つ人だけが利用できるように自動で制限</strong>され、かつ自身の権限で実行されます！</em></p>
</blockquote>

<blockquote>
  <p><em>とても便利な権限管理機能です！</em></p>
</blockquote>

<p>選択後、右下の「デプロイ」をクリックします。</p>

<p><img src="/assets/4cb4437818f2/1*dvyqYb5kcta402j3RUYJog.webp" alt="" loading="lazy" decoding="async" width="770" height="605" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzAiIGhlaWdodD0iNjA1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*dvyqYb5kcta402j3RUYJog.png" /></p>

<p>ウェブアプリケーションのURLは、Web AppのアクセスURLです。</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://script.google.com/macros/s/AKfycbw8SuK7lLLMdY86y3jxMJyzXqa5tdxJryRnteOnNi-lK--j6CmKYXj7UuU58DiS0NSVvA/exec
</code></pre></div></div>

<blockquote>
  <p><em>URLが長くて見た目が悪いですが、仕方なく自分で短縮URLツールを使って短くしました。</em></p>
</blockquote>

<p><strong>リンクをクリックしてページの効果を確認：</strong></p>

<p><img src="/assets/4cb4437818f2/1*jbx4IO4DEhqYfwI_UTQk5Q.webp" alt="" loading="lazy" decoding="async" width="709" height="641" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDkiIGhlaWdodD0iNjQxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*jbx4IO4DEhqYfwI_UTQk5Q.png" /></p>

<p><strong>ここでGASの制限を2つ挙げておきます：</strong></p>

<ul>
  <li>
    <p>GAS Web App 上部の警告メッセージは、デフォルトで非表示にできません</p>
  </li>
  <li>
    <p>GAS Web App は IFrame を使って私たちのページを埋め込んでいるため、100% のレスポンシブデザインを実現するのは難しいです。<br />
<code class="language-plaintext highlighter-rouge">.setWidth()</code> を使ってウィンドウの幅を調整するしかありません。</p>
  </li>
</ul>

<h4 id="google-apps-script-の認証警告">Google Apps Script の認証警告</h4>

<p><strong>初めて使用する場合</strong>、「デバッグ」または「実行」をクリックすると、以下の認証警告が表示されることがあります：</p>

<p><img src="/assets/4cb4437818f2/1*9q8KZGHER9vdtnbKVVQB9g.webp" alt="" loading="lazy" decoding="async" width="301" height="196" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDEiIGhlaWdodD0iMTk2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*9q8KZGHER9vdtnbKVVQB9g.png" /></p>

<p><img src="/assets/4cb4437818f2/1*iWrkqMf8vkEGkiwkI1amIw.webp" alt="" loading="lazy" decoding="async" width="521" height="503" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MjEiIGhlaWdodD0iNTAzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*iWrkqMf8vkEGkiwkI1amIw.jpeg" /></p>

<p>実行したいアカウントを選択し、「このアプリは Google によって確認されていません」というメッセージが表示された場合は、「詳細」-&gt;「XXX（安全ではありません）に移動」をクリックし、「許可」を選択してください：</p>

<p><img src="/assets/4cb4437818f2/1*ucaqLxh-TOgJIaGyqqFd3A.webp" alt="" loading="lazy" decoding="async" width="504" height="595" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MDQiIGhlaWdodD0iNTk1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*ucaqLxh-TOgJIaGyqqFd3A.png" /></p>

<p><img src="/assets/4cb4437818f2/1*l-tma_YICU24goKvZvl7Ww.webp" alt="" loading="lazy" decoding="async" width="653" height="468" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NTMiIGhlaWdodD0iNDY4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*l-tma_YICU24goKvZvl7Ww.png" /></p>

<p><img src="/assets/4cb4437818f2/1*JAs_3__Qt2XeDcQiKEUNhg.webp" alt="" loading="lazy" decoding="async" width="504" height="789" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MDQiIGhlaWdodD0iNzg5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*JAs_3__Qt2XeDcQiKEUNhg.png" /></p>

<p>GAS プログラムの権限に変更があった場合（例：Google Sheet へのアクセス権追加など）にのみ再認証が必要で、それ以外は一度認証すれば再度表示されることはありません。</p>

<blockquote>
  <p><em>もし「XXX」へのアクセス権がブロックされており、Google認証手続きが完了していない場合は、<a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/">私の最新記事のGCP設定</a>を参照してください。</em></p>
</blockquote>

<h4 id="step-3-github-apiを連携してprブランチ一覧を取得する">Step 3. Github APIを連携してPRブランチ一覧を取得する</h4>

<p>私たちは <code class="language-plaintext highlighter-rouge">Github.gs</code> というファイルを新たに作成し、Github API に関するロジックを格納します。</p>

<p><code class="language-plaintext highlighter-rouge">Github.gs：</code></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// SECRET</span>
<span class="kd">const</span> <span class="nx">githubPersonalAccessToken</span> <span class="o">=</span> <span class="dl">""</span>
<span class="c1">// あなたの Github アカウントまたは組織で共有している Github アカウントで PAT を作成してください</span>
<span class="c1">// https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens</span>

<span class="c1">// 方法 1: Restful API アクセス</span>
<span class="kd">function</span> <span class="nf">githubAPI</span><span class="p">(</span><span class="nx">method</span><span class="p">,</span> <span class="nx">path</span><span class="p">,</span> <span class="nx">payload</span> <span class="o">=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">try</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://api.github.com</span><span class="dl">"</span><span class="o">+</span><span class="nx">path</span><span class="p">;</span>  
    <span class="kd">var</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
      <span class="na">method</span><span class="p">:</span> <span class="nx">method</span><span class="p">,</span>
      <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
        <span class="dl">"</span><span class="s2">Accept</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/vnd.github+json</span><span class="dl">"</span><span class="p">,</span>
        <span class="dl">"</span><span class="s2">Authorization</span><span class="dl">"</span><span class="p">:</span> <span class="s2">`Bearer </span><span class="p">${</span><span class="nx">githubPersonalAccessToken</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span>
        <span class="dl">"</span><span class="s2">X-GitHub-Api-Version</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">2022-11-28</span><span class="dl">"</span>
      <span class="p">}</span>
    <span class="p">};</span>

    <span class="k">if </span><span class="p">(</span><span class="nx">method</span><span class="p">.</span><span class="nf">toLowerCase</span><span class="p">().</span><span class="nf">trim</span><span class="p">()</span> <span class="o">==</span> <span class="dl">"</span><span class="s2">post</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">options</span><span class="p">.</span><span class="nx">payload</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">payload</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
    <span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span>
    <span class="k">return</span> <span class="nx">data</span><span class="p">;</span>
  <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// 方法 2: GraphQL アクセス</span>
<span class="c1">// Github API のより詳細なクエリ機能は GraphQL API のみ提供</span>
<span class="c1">// https://docs.github.com/en/graphql</span>
<span class="kd">function</span> <span class="nf">githubGraphQL</span><span class="p">(</span><span class="nx">query</span><span class="p">,</span> <span class="nx">variables</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://api.github.com/graphql</span><span class="dl">"</span><span class="p">;</span>
  <span class="kd">const</span> <span class="nx">payload</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">query</span><span class="p">:</span> <span class="nx">query</span><span class="p">,</span>
    <span class="na">variables</span><span class="p">:</span> <span class="nx">variables</span>
  <span class="p">};</span>

  <span class="kd">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">post</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">contentType</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
      <span class="dl">"</span><span class="s2">Accept</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/vnd.github+json</span><span class="dl">"</span><span class="p">,</span>
      <span class="dl">"</span><span class="s2">Authorization</span><span class="dl">"</span><span class="p">:</span> <span class="s2">`Bearer </span><span class="p">${</span><span class="nx">githubPersonalAccessToken</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span>
      <span class="dl">"</span><span class="s2">X-GitHub-Api-Version</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">2022-11-28</span><span class="dl">"</span>
    <span class="p">},</span>
    <span class="na">payload</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">payload</span><span class="p">)</span>
  <span class="p">};</span>

  <span class="k">try</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
    <span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span>
    <span class="k">return</span> <span class="nx">data</span><span class="p">;</span>
  <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// GraphQL 例:</span>
<span class="c1">// const query = `</span>
<span class="c1">//   query($owner: String!, $repo: String!) {</span>
<span class="c1">//     repository(owner: $owner, name: $repo) {</span>
<span class="c1">//       pullRequests(states: OPEN, first: 100, orderBy: { field: CREATED_AT, direction: DESC }) {</span>
<span class="c1">//         nodes {</span>
<span class="c1">//           title</span>
<span class="c1">//           url</span>
<span class="c1">//           number</span>
<span class="c1">//           createdAt</span>
<span class="c1">//           author {</span>
<span class="c1">//             login</span>
<span class="c1">//           }</span>
<span class="c1">//           headRefName</span>
<span class="c1">//           baseRefName</span>
<span class="c1">//           body</span>
<span class="c1">//         }</span>
<span class="c1">//         pageInfo {</span>
<span class="c1">//           hasNextPage</span>
<span class="c1">//           endCursor</span>
<span class="c1">//         }</span>
<span class="c1">//       }</span>
<span class="c1">//     }</span>
<span class="c1">//   }</span>
<span class="c1">// `;</span>
<span class="c1">// const variables = {</span>
<span class="c1">//   owner: "swiftlang",</span>
<span class="c1">//   repo: "swift"</span>
<span class="c1">// };</span>
<span class="c1">// const response = githubGraphQL(query, variables);</span>
</code></pre></div></div>

<p>Github API には2つのアクセス方法があります。1つは従来の Restful、もう1つはより柔軟な GraphQLです。本記事では Restful を例に説明します。</p>

<p><code class="language-plaintext highlighter-rouge">コード.gs：</code></p>

<div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">function</span> <span class="nf">doGet</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="p">{</span>
  <span class="c1">// 左側ファイル Form.html に対応</span>
  <span class="k">const</span> <span class="n">htmlTemplate</span> <span class="p">=</span> <span class="nc">HtmlService</span><span class="p">.</span><span class="nf">createTemplateFromFile</span><span class="p">(</span><span class="err">'</span><span class="nc">Form</span><span class="err">'</span><span class="p">);</span>
  
  <span class="k">const</span> <span class="n">email</span> <span class="p">=</span> <span class="nc">Session</span><span class="p">.</span><span class="nf">getActiveUser</span><span class="p">().</span><span class="nf">getEmail</span><span class="p">();</span>
  <span class="c1">// ユーザーのメールアドレスを取得、実行権限：ウェブアプリを実行するユーザーのみ有効</span>

  <span class="k">const</span> <span class="n">title</span> <span class="p">=</span> <span class="s">"App CD パッケージリクエストフォーム"</span><span class="p">;</span>
  
  <span class="k">const</span> <span class="n">pullRequests</span> <span class="p">=</span> <span class="nf">githubAPI</span><span class="p">(</span><span class="s">"get"</span><span class="p">,</span> <span class="s">"/repos/swiftlang/swift/pulls"</span><span class="p">);</span>
  <span class="c1">// 例：https://github.com/swiftlang/swift/pulls</span>
  
  <span class="k">const</span> <span class="n">buildNumber</span> <span class="p">=</span> <span class="nf">genBuildNumber</span><span class="p">();</span>

  <span class="n">htmlTemplate</span><span class="p">.</span><span class="n">email</span> <span class="p">=</span> <span class="n">email</span><span class="p">;</span>
  <span class="n">htmlTemplate</span><span class="p">.</span><span class="n">title</span> <span class="p">=</span> <span class="n">title</span><span class="p">;</span>
  <span class="n">htmlTemplate</span><span class="p">.</span><span class="n">pullRequests</span> <span class="p">=</span> <span class="n">pullRequests</span><span class="p">;</span>
  <span class="n">htmlTemplate</span><span class="p">.</span><span class="n">buildNumber</span> <span class="p">=</span> <span class="n">buildNumber</span><span class="p">;</span>

  <span class="k">const</span> <span class="n">html</span> <span class="p">=</span> <span class="n">htmlTemplate</span><span class="p">.</span><span class="nf">evaluate</span><span class="p">();</span>
  <span class="n">html</span><span class="p">.</span><span class="nf">setTitle</span><span class="p">(</span><span class="n">title</span><span class="p">);</span>
  <span class="c1">//html.setWidth(600) // ページ幅を設定</span>

  <span class="k">return</span> <span class="n">html</span>
<span class="p">}</span>

<span class="n">function</span> <span class="nf">processForm</span><span class="p">(</span><span class="k">object</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="k">object</span><span class="p">.</span><span class="n">buildNumber</span> <span class="p">==</span> <span class="s">""</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span><span class="s">"ok"</span><span class="p">:</span> <span class="k">false</span><span class="p">,</span> <span class="s">"message"</span><span class="p">:</span> <span class="s">"バージョン番号を入力してください！"</span><span class="p">};</span>
  <span class="p">}</span>
  <span class="k">if</span> <span class="p">(</span><span class="k">object</span><span class="p">.</span><span class="n">branch</span> <span class="p">==</span> <span class="s">""</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span><span class="s">"ok"</span><span class="p">:</span> <span class="k">false</span><span class="p">,</span> <span class="s">"message"</span><span class="p">:</span> <span class="s">"ブランチバージョンを選択してください！"</span><span class="p">};</span>
  <span class="p">}</span>

  <span class="c1">// Github Action に渡すパラメータ</span>
  <span class="k">const</span> <span class="n">payload</span> <span class="p">=</span> <span class="p">{</span>
    <span class="n">ref</span><span class="p">:</span> <span class="k">object</span><span class="p">.</span><span class="n">branch</span><span class="p">,</span>
    <span class="n">inputs</span><span class="p">:</span> <span class="p">{</span>
      <span class="n">buildNumber</span><span class="p">:</span> <span class="k">object</span><span class="p">.</span><span class="n">buildNumber</span>
    <span class="p">}</span>
  <span class="p">};</span>
  
  <span class="c1">//  </span>
  <span class="k">try</span> <span class="p">{</span>
    <span class="k">const</span> <span class="n">response</span> <span class="p">=</span> <span class="nf">githubAPI</span><span class="p">(</span><span class="s">"post"</span><span class="p">,</span> <span class="s">"/repos/zhgchgli0718/ios-project-for-github-action-ci-cd-demo/actions/workflows/CD-Job.yml/dispatches"</span><span class="p">,</span> <span class="n">payload</span><span class="p">);</span>
    <span class="c1">// 例：https://github.com/zhgchgli0718/ios-project-for-github-action-ci-cd-demo/blob/main/.github/workflows/CD-Job.yml</span>

    <span class="k">return</span> <span class="p">{</span><span class="s">"ok"</span><span class="p">:</span> <span class="k">true</span><span class="p">,</span> <span class="s">"message"</span><span class="p">:</span> <span class="err">`パッケ</span><span class="n">ー</span><span class="err">ジリクエストを送信しました！</span><span class="p">&lt;</span><span class="n">br</span><span class="p">/&gt;</span><span class="err">対象ブランチ：</span><span class="p">&lt;</span><span class="n">strong</span><span class="p">&gt;</span><span class="err">$</span><span class="p">{</span><span class="k">object</span><span class="p">.</span><span class="n">branch</span><span class="p">}&lt;/</span><span class="n">strong</span><span class="p">&gt;&lt;</span><span class="n">br</span><span class="p">/&gt;</span><span class="err">バ</span><span class="n">ー</span><span class="err">ジョン番号：</span><span class="p">&lt;</span><span class="n">strong</span><span class="p">&gt;</span><span class="err">$</span><span class="p">{</span><span class="k">object</span><span class="p">.</span><span class="n">buildNumber</span><span class="p">}&lt;/</span><span class="n">strong</span><span class="p">&gt;</span><span class="err">`</span><span class="p">};</span>
  <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span><span class="s">"ok"</span><span class="p">:</span> <span class="k">false</span><span class="p">,</span> <span class="s">"message"</span><span class="p">:</span> <span class="s">"エラーが発生しました："</span><span class="p">+</span><span class="n">error</span><span class="p">.</span><span class="n">message</span><span class="p">};</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">processForm</code> メソッドではフォームの送信内容を処理しますが、さらに多くの処理を追加することもできます。</p>

<h4 id="gas-x-github-api-x-github-action">GAS x Github API x Github Action</h4>

<p>こちらに対応する Github Action を補足します。</p>

<p><code class="language-plaintext highlighter-rouge">CD-Job.yml：</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># CD パッケージングジョブ</span>

<span class="na">name</span><span class="pi">:</span> <span class="s">CD-Job</span>

<span class="na">on</span><span class="pi">:</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>
    <span class="na">inputs</span><span class="pi">:</span>
      <span class="na">buildNumber</span><span class="pi">:</span> <span class="c1"># GAS payload.inputs.xxx に対応</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">バージョン番号'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="c1"># ...その他</span>
      <span class="c1"># 入力タイプは公式ドキュメントを参照してください：https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onworkflow_dispatchinputs</span>
      
<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">some-job</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">入力値を表示</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">\\|</span>
          <span class="s">echo "Release Build Number</span><span class="err">:</span> <span class="s">${{ github.event.inputs.buildNumber }}"</span>    
</code></pre></div></div>

<h4 id="step-4-google-apps-script-web-app-フォームの再デプロイ">Step 4. Google Apps Script Web App フォームの再デプロイ</h4>

<blockquote>
  <p><strong><em>⚠️ご注意ください。GASのコードを変更した場合は、再デプロイが必要で反映されます。⚠️</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>⚠️ご注意ください。GASのコードを変更した場合は、再デプロイが必要で反映されます。⚠️</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>⚠️ご注意ください。GASのコードを変更した場合は、再デプロイが必要で反映されます。⚠️</em></strong></p>
</blockquote>

<p>GAS 右上の「デプロイ」-&gt; 右上の「編集」を選択-&gt; バージョンで「新しいバージョンを作成」を選択</p>

<p><img src="/assets/4cb4437818f2/1*ZMAB_m6HmsSsGSqqfZiRpA.webp" alt="" loading="lazy" decoding="async" width="208" height="238" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDgiIGhlaWdodD0iMjM4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*ZMAB_m6HmsSsGSqqfZiRpA.png" /></p>

<p><img src="/assets/4cb4437818f2/1*rUWlfzASAaeXcXUh4LavZw.webp" alt="" loading="lazy" decoding="async" width="776" height="619" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzYiIGhlaWdodD0iNjE5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*rUWlfzASAaeXcXUh4LavZw.png" /></p>

<p><img src="/assets/4cb4437818f2/1*HAr5TZtpnQeG-Ril0Rjf-g.webp" alt="" loading="lazy" decoding="async" width="782" height="612" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3ODIiIGhlaWdodD0iNjEyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*HAr5TZtpnQeG-Ril0Rjf-g.png" /></p>

<p>「デプロイ」-&gt; 完了 をクリックしてください。</p>

<p><img src="/assets/4cb4437818f2/1*z6lw7R8ivUseSzR4IZgPdg.webp" alt="" loading="lazy" decoding="async" width="777" height="611" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzciIGhlaWdodD0iNjExIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*z6lw7R8ivUseSzR4IZgPdg.png" /></p>

<p><img src="/assets/4cb4437818f2/1*eTdgKGQ1lRM7sCRXQgZ-DA.webp" alt="" loading="lazy" decoding="async" width="770" height="610" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzAiIGhlaWdodD0iNjEwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*eTdgKGQ1lRM7sCRXQgZ-DA.png" /></p>

<p><strong>再びウェブページをリロードすると、変更後の結果が表示されます：</strong></p>

<p><img src="/assets/4cb4437818f2/1*iI49OJC1uTyMEgzGTBowxQ.webp" alt="" loading="lazy" decoding="async" width="657" height="583" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NTciIGhlaWdodD0iNTgzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*iI49OJC1uTyMEgzGTBowxQ.png" /></p>

<blockquote>
  <p><strong><em>⚠️ご注意ください。GASのコードを変更した場合は、再デプロイが必要で反映されます。⚠️</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>⚠️ご注意ください。GASのコードを変更した場合は、再デプロイが必要で反映されます。⚠️</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>⚠️ご注意ください。GASのコードを変更した場合は、再デプロイが必要で反映されます。⚠️</em></strong></p>
</blockquote>

<h3 id="完了">完了！🎉🎉🎉</h3>

<p><img src="/assets/4cb4437818f2/1*pzW-Yki-4HbE2nYXC4q-Aw.webp" alt="" loading="lazy" decoding="async" width="653" height="672" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NTMiIGhlaWdodD0iNjcyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*pzW-Yki-4HbE2nYXC4q-Aw.png" /></p>

<p><img src="/assets/4cb4437818f2/1*9aaNeemezNPRlSgbLFrseA.webp" alt="Demo Web Appフォーム" loading="lazy" decoding="async" width="648" height="628" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NDgiIGhlaWdodD0iNjI4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*9aaNeemezNPRlSgbLFrseA.png" /></p>

<p><a href="https://script.google.com/macros/s/AKfycbw8SuK7lLLMdY86y3jxMJyzXqa5tdxJryRnteOnNi-lK--j6CmKYXj7UuU58DiS0NSVvA/exec" target="_blank">Demo Web App Form</a></p>

<p>現在、組織内でこのリンクを他のメンバーと共有すれば、彼らはこのウェブGUIを使って直接CI/CD作業を実行できます。</p>

<h4 id="拡張-1-ユーザーのメールアドレスで-slack-user-id-を検索し進捗通知を送信更新する">拡張 (1)— ユーザーのメールアドレスで Slack User ID を検索し、進捗通知を送信・更新する</h4>

<p>前文で述べたように、CI/CDの実行状況をリアルタイムでユーザーに通知したい場合、ユーザーが提供したメールアドレスを使ってSlackのユーザーIDを取得できます。</p>

<p><code class="language-plaintext highlighter-rouge">Slack.gs：</code></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">slackBotToken</span> <span class="o">=</span> <span class="dl">""</span>
<span class="c1">// https://medium.com/zrealm-robotic-process-automation/slack-chatgpt-integration-bd94cc88f9c9</span>

<span class="kd">function</span> <span class="nf">slackRequest</span><span class="p">(</span><span class="nx">path</span><span class="p">,</span> <span class="nx">content</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">post</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">contentType</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">Authorization</span><span class="p">:</span> <span class="s2">`Bearer </span><span class="p">${</span><span class="nx">slackBotToken</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span> <span class="c1">// ボットトークンを使って認証</span>
      <span class="dl">'</span><span class="s1">X-Slack-No-Retry</span><span class="dl">'</span><span class="p">:</span> <span class="mi">1</span>
    <span class="p">},</span>
    <span class="na">payload</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">content</span><span class="p">)</span>
  <span class="p">};</span>

  <span class="k">try</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="dl">"</span><span class="s2">https://slack.com/api/</span><span class="dl">"</span><span class="o">+</span><span class="nx">path</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
    <span class="kd">const</span> <span class="nx">responseData</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">responseData</span><span class="p">.</span><span class="nx">ok</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span> <span class="nx">responseData</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="s2">`Slack: </span><span class="p">${</span><span class="nx">responseData</span><span class="p">.</span><span class="nx">error</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// メールアドレスでSlack UIDを取得</span>
<span class="kd">function</span> <span class="nf">getSlackUserId</span><span class="p">(</span><span class="nx">email</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nf">slackRequest</span><span class="p">(</span><span class="s2">`users.lookupByEmail?email=</span><span class="p">${</span><span class="nf">encodeURIComponent</span><span class="p">(</span><span class="nx">email</span><span class="p">)}</span><span class="s2">`</span><span class="p">)?.</span><span class="nx">user</span><span class="p">?.</span><span class="nx">id</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// 対象Slack UID（channelID）にメッセージを送信</span>
<span class="kd">function</span> <span class="nf">sendSlackMessage</span><span class="p">(</span><span class="nx">channelId</span><span class="p">,</span> <span class="nx">ts</span> <span class="o">=</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span>  <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">content</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">channel</span><span class="p">:</span> <span class="nx">channelId</span>
  <span class="p">};</span>

  <span class="k">if </span><span class="p">(</span><span class="nx">ts</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">content</span><span class="p">.</span><span class="nx">thread_ts</span> <span class="o">=</span> <span class="nx">ts</span><span class="p">;</span>
  <span class="p">}</span>
  
  <span class="k">if </span><span class="p">(</span><span class="k">typeof</span> <span class="nx">value</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">string</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">content</span><span class="p">.</span><span class="nx">text</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="nx">content</span><span class="p">.</span><span class="nx">blocks</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="k">return</span> <span class="nf">slackRequest</span><span class="p">(</span><span class="dl">"</span><span class="s2">chat.postMessage</span><span class="dl">"</span><span class="p">,</span> <span class="nx">content</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// 送信したメッセージ内容を更新</span>
<span class="kd">function</span> <span class="nf">updateSlackMessage</span><span class="p">(</span><span class="nx">channelId</span><span class="p">,</span> <span class="nx">ts</span> <span class="o">=</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span>  <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">content</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">channel</span><span class="p">:</span> <span class="nx">channelId</span>
  <span class="p">};</span>

  <span class="k">if </span><span class="p">(</span><span class="nx">ts</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">content</span><span class="p">.</span><span class="nx">ts</span> <span class="o">=</span> <span class="nx">ts</span><span class="p">;</span>
  <span class="p">}</span>
  
  <span class="k">if </span><span class="p">(</span><span class="k">typeof</span> <span class="nx">value</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">string</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">content</span><span class="p">.</span><span class="nx">text</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="nx">content</span><span class="p">.</span><span class="nx">blocks</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="k">return</span> <span class="nf">slackRequest</span><span class="p">(</span><span class="dl">"</span><span class="s2">chat.update</span><span class="dl">"</span><span class="p">,</span> <span class="nx">content</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Slack API の使用については、<a href="https://api.slack.com/methods/chat.postMessage" target="_blank">公式ドキュメント</a> をご参照ください。</p>

<p><strong>Githun Action YAML では、この Action を使ってメッセージを継続的に更新したり、Slack メッセージを送信したりできます：</strong></p>

<p><a href="https://github.com/slackapi/slack-github-action" target="_blank"><img src="https://opengraph.githubassets.com/4b7679d54edd2c5fbafdaa5a79df23035f15b7a3eda256a43b710aab59a6164e/slackapi/slack-github-action" alt="" /></a></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ...</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="na">workflow_dispatch</span><span class="pi">:</span>
    <span class="na">inputs</span><span class="pi">:</span>
      <span class="na">buildNumber</span><span class="pi">:</span> <span class="c1"># GASのpayload.inputs.xxxに対応</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">バージョン番号'</span>
        <span class="na">required</span><span class="pi">:</span> <span class="kc">false</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="c1"># ...その他</span>
      <span class="na">SLACK_USER_ID</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">アクション通知を受け取るSlackユーザーID'</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="na">SLACK_CHANNEL_ID</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">アクション通知を受け取るSlackチャンネルID'</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      <span class="na">SLACK_THREAD_TS</span><span class="pi">:</span>
        <span class="na">description</span><span class="pi">:</span> <span class="s1">'</span><span class="s">Slackメッセージのts'</span>
        <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
      
<span class="na">jobs</span><span class="pi">:</span>
  <span class="c1"># ジョブの一部...</span>

  <span class="na">if-deploy-failed-message</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">if</span><span class="pi">:</span> <span class="s">failure()</span>
      <span class="s">- name</span><span class="err">:</span> <span class="s">slackメッセージを更新</span>
        <span class="s">uses</span><span class="err">:</span> <span class="s">slackapi/slack-github-action@v2.0.0</span>
        <span class="s">with</span><span class="err">:</span>
            <span class="na">method</span><span class="pi">:</span> <span class="s">chat.update</span>
            <span class="na">token</span><span class="pi">:</span> <span class="s">${{ secrets.SLACK_BOT_TOKEN }}</span>
            <span class="na">payload</span><span class="pi">:</span> <span class="s">\\|</span>
              <span class="s">channel</span><span class="err">:</span> <span class="s">${{ github.event.inputs.SLACK_CHANNEL_ID }}</span>
              <span class="s">ts</span><span class="err">:</span> <span class="s">${{ github.event.inputs.SLACK_THREAD_TS }}</span>
              <span class="s">text</span><span class="err">:</span> <span class="s2">"</span><span class="s">❌</span><span class="nv"> </span><span class="s">パッケージングタスクが失敗しました。実行状況の結果を確認するか、後でもう一度お試しください。</span><span class="se">\n</span><span class="s">&lt;${{</span><span class="nv"> </span><span class="s">github.server_url</span><span class="nv"> </span><span class="s">}}/${{</span><span class="nv"> </span><span class="s">github.repository</span><span class="nv"> </span><span class="s">}}/actions/runs/${{</span><span class="nv"> </span><span class="s">github.run_id</span><span class="nv"> </span><span class="s">}}</span><span class="se">\\</span><span class="s">|実行状況を見る&gt;</span><span class="nv"> </span><span class="s">cc'ed</span><span class="nv"> </span><span class="s">&lt;@${{</span><span class="nv"> </span><span class="s">github.event.inputs.SLACK_USER_ID</span><span class="nv"> </span><span class="s">}}&gt;"</span>
</code></pre></div></div>

<p><strong>効果：</strong></p>

<p><img src="/assets/4cb4437818f2/1*-w5jqjkx6p2alpzlLcz_Nw.webp" alt="" loading="lazy" decoding="async" width="428" height="559" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MjgiIGhlaWdodD0iNTU5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/4cb4437818f2/1*-w5jqjkx6p2alpzlLcz_Nw.png" /></p>

<blockquote>
  <p><strong><em>Slack App の連携詳細は、以前の記事をご参照ください： <a href="/posts/zrealm-ロボティックプロセスオートメーション/slackとchatgpt連携-openai-apiで自作slackアプリをpythonとgoogle-cloud-functionsで実装-bd94cc88f9c9/">Slack &amp; ChatGPT Integration</a> 。</em></strong></p>
</blockquote>

<h4 id="拡張-2--jira-チケットの検索">拡張 (2) — Jira チケットの検索</h4>

<p><code class="language-plaintext highlighter-rouge">Jira.gs：</code></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">jiraPersonalAccessToken</span> <span class="o">=</span> <span class="dl">""</span>
<span class="c1">// https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html</span>

<span class="kd">function</span> <span class="nf">getJiraTickets</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="s2">`https://xxx.atlassian.net/rest/api/3/search`</span><span class="p">;</span>

  <span class="c1">// JQLクエリ</span>
  <span class="kd">const</span> <span class="nx">jql</span> <span class="o">=</span> <span class="s2">`project = XXX`</span><span class="p">;</span>
  <span class="kd">const</span> <span class="nx">queryParams</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">jql</span><span class="p">:</span> <span class="nx">jql</span><span class="p">,</span>
    <span class="na">maxResults</span><span class="p">:</span> <span class="mi">50</span><span class="p">,</span> <span class="c1">// 必要に応じて調整</span>
  <span class="p">};</span>

  <span class="kd">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">get</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">Authorization</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Basic </span><span class="dl">"</span> <span class="o">+</span> <span class="nx">jiraPersonalAccessToken</span><span class="p">,</span>
      <span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span>
    <span class="p">},</span>
    <span class="na">muteHttpExceptions</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
  <span class="p">};</span>

  <span class="kd">const</span> <span class="nx">queryString</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nf">keys</span><span class="p">(</span><span class="nx">queryParams</span><span class="p">).</span><span class="nf">map</span><span class="p">(</span><span class="nx">key</span> <span class="o">=&gt;</span> <span class="s2">`</span><span class="p">${</span><span class="nf">encodeURIComponent</span><span class="p">(</span><span class="nx">key</span><span class="p">)}</span><span class="s2">=</span><span class="p">${</span><span class="nf">encodeURIComponent</span><span class="p">(</span><span class="nx">queryParams</span><span class="p">[</span><span class="nx">key</span><span class="p">])}</span><span class="s2">`</span><span class="p">).</span><span class="nf">join</span><span class="p">(</span><span class="dl">"</span><span class="s2">&amp;</span><span class="dl">"</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="nx">url</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">?</span><span class="dl">"</span> <span class="o">+</span> <span class="nx">queryString</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">&amp;fields=</span><span class="dl">"</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
  <span class="c1">// 特定のフィールドのみ返すことも可能</span>

  <span class="k">if </span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getResponseCode</span><span class="p">()</span> <span class="o">===</span> <span class="mi">200</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">issues</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">()).</span><span class="nx">issues</span><span class="p">;</span>
    <span class="k">return</span> <span class="nx">issues</span><span class="p">;</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="nx">Logger</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Error: </span><span class="p">${</span><span class="nx">response</span><span class="p">.</span><span class="nf">getResponseCode</span><span class="p">()}</span><span class="s2"> - </span><span class="p">${</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">()}</span><span class="s2">`</span><span class="p">);</span>
    <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Jiraの課題取得に失敗しました。</span><span class="dl">"</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span> 
</code></pre></div></div>

<p>その他の Jira API の使用については、<a href="https://developer.atlassian.com/cloud/jira/platform/rest/v3/" target="_blank">公式ドキュメント</a> を参照してください。</p>

<h4 id="拡張-3--asana-タスクの検索">拡張 (3) — Asana タスクの検索</h4>

<p><code class="language-plaintext highlighter-rouge">Asana.gs：</code></p>

<div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">const</span> <span class="n">asanaPersonalAccessToken</span> <span class="p">=</span> <span class="s">""</span>
<span class="c1">// https://developers.asana.com/docs/personal-access-token</span>

<span class="n">function</span> <span class="nf">asanaAPI</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">method</span> <span class="p">=</span> <span class="s">"GET"</span><span class="p">,</span> <span class="n">data</span> <span class="p">=</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="py">options</span> <span class="p">=</span> <span class="p">{</span>
      <span class="s">"method"</span> <span class="p">:</span> <span class="n">method</span><span class="p">,</span>
      <span class="s">"contentType"</span> <span class="p">:</span> <span class="s">"application/json"</span><span class="p">,</span>
      <span class="s">"headers"</span><span class="p">:</span> <span class="p">{</span>
          <span class="s">"Authorization"</span><span class="p">:</span>  <span class="s">"Bearer "</span><span class="p">+</span><span class="n">asanaPersonalAccessToken</span>
      <span class="p">}</span>
    <span class="p">};</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">data</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
      <span class="n">options</span><span class="p">[</span><span class="s">"payload"</span><span class="p">]</span> <span class="p">=</span> <span class="nc">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">({</span><span class="s">"data"</span><span class="p">:</span><span class="n">data</span><span class="p">});</span>
    <span class="p">}</span>

    <span class="k">const</span> <span class="n">url</span> <span class="p">=</span> <span class="s">"https://app.asana.com/api/1.0"</span><span class="p">+</span><span class="n">endpoint</span><span class="p">;</span>
    <span class="k">const</span> <span class="n">res</span> <span class="p">=</span> <span class="nc">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">options</span><span class="p">);</span>
    <span class="k">const</span> <span class="n">data</span> <span class="p">=</span> <span class="nc">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span>
    <span class="k">return</span> <span class="n">data</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// プロジェクト内のタスクを検索</span>
<span class="c1">// asanaAPI("/projects/PROJECT_ID/tasks");</span>
</code></pre></div></div>

<p>その他の Asana API の使用方法については、<a href="https://developers.asana.com/reference/gettasksforproject" target="_blank">公式ドキュメント</a> を参照してください。</p>

<h3 id="まとめ">まとめ</h3>

<p>自動化や業務・開発プロセスの改善に不足しているのは技術ではなくアイデアです。アイデアさえあれば、私たちはそれを実現するための適切な技術を必ず見つけられます。共に頑張りましょう！</p>

<h3 id="202507-アップデート-1">2025/07 アップデート:</h3>

<p>この機能は実際のパッケージングツールに統合されています。最新の記事の事例をご参照ください：「<a href="/posts/zrealm-dev/google-apps-script-web-app-github-actions連携で無料ci-cd打包ツール構築-跨團隊共有を実現-4273e57e7148/"><strong>CI/CD 実践ガイド（4）：Google Apps Script Web App を使って GitHub Actions と連携し、無料で使いやすいパッケージングツールプラットフォームを構築する</strong></a>」</p>

<p><em><a href="https://medium.com/zrealm-ios-dev/%E4%BD%BF%E7%94%A8-google-apps-script-web-app-%E8%A1%A8%E5%96%AE%E4%B8%B2%E6%8E%A5-github-action-ci-cd-%E5%B7%A5%E4%BD%9C-4cb4437818f2" target="_blank">Post</a> Mediumから変換 by <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>.</em></p>]]></content>
  </entry><entry>
    <title type="html">Swift｜優雅な原生型拡張でNamespace機能を実現｜効率的なコード管理術</title>
    <link href="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/swift-%E5%84%AA%E9%9B%85%E3%81%AA%E5%8E%9F%E7%94%9F%E5%9E%8B%E6%8B%A1%E5%BC%B5%E3%81%A7namespace%E6%A9%9F%E8%83%BD%E3%82%92%E5%AE%9F%E7%8F%BE-%E5%8A%B9%E7%8E%87%E7%9A%84%E3%81%AA%E3%82%B3%E3%83%BC%E3%83%89%E7%AE%A1%E7%90%86%E8%A1%93-a8925ad9ed01/" rel="alternate" type="text/html" title="Swift｜優雅な原生型拡張でNamespace機能を実現｜効率的なコード管理術" />
    <published>2025-01-01T22:02:32+08:00</published>
    <updated>2025-01-01T22:02:32+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/a8925ad9ed01</id><summary type="html">Swiftの原生型を拡張しNamespace機能を持たせる方法を解説。拡張メソッドを自作で整理し、コードの可読性と保守性を大幅に向上させる実践テクニックを紹介します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm開発" /><category term="iosアプリ開発" /><category term="swift" /><category term="ラッパー" /><category term="アプリのモジュール化" /><category term="ios" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/a8925ad9ed01/1*kJFHiAuTZ8TP-4aTa_daqA.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm%E9%96%8B%E7%99%BA/swift-%E5%84%AA%E9%9B%85%E3%81%AA%E5%8E%9F%E7%94%9F%E5%9E%8B%E6%8B%A1%E5%BC%B5%E3%81%A7namespace%E6%A9%9F%E8%83%BD%E3%82%92%E5%AE%9F%E7%8F%BE-%E5%8A%B9%E7%8E%87%E7%9A%84%E3%81%AA%E3%82%B3%E3%83%BC%E3%83%89%E7%AE%A1%E7%90%86%E8%A1%93-a8925ad9ed01/"><![CDATA[<h3 id="swift-優雅なネイティブ型拡張方法">[Swift] 優雅な<strong>ネイティブ型拡張方法</strong></h3>

<p>拡張メソッドを独自にラップして、Namespace機能を持たせる</p>

<p><img src="/assets/a8925ad9ed01/1*kJFHiAuTZ8TP-4aTa_daqA.webp" alt="&lt;https://www.swift.org/&gt;" loading="lazy" decoding="async" width="1352" height="484" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzUyIiBoZWlnaHQ9IjQ4NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/a8925ad9ed01/1*kJFHiAuTZ8TP-4aTa_daqA.png" /></p>

<p><a href="https://www.swift.org/" target="_blank">https://www.swift.org/</a></p>

<blockquote>
  <p><em>実際の出典は不明で、優秀な同僚のコードから学んだものです。</em></p>
</blockquote>

<h3 id="ネイティブ型の拡張">ネイティブ型の拡張</h3>

<p>日常の iOS/Swift 開発では、ネイティブ API を拡張したり、自分のヘルパーを作成したりすることがよくあります。</p>

<p><strong>以下は UIColor を拡張する例です。UIColor を拡張して HEX カラー文字列に変換できるようにします：</strong></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">UIColor</span> <span class="p">{</span>
    <span class="c1">/// UIColorを16進数の文字列に変換します。</span>
    <span class="c1">/// - Returns: 16進数の文字列（例: "#RRGGBB" または "#RRGGBBAA"）。</span>
    <span class="kd">func</span> <span class="nf">toHexString</span><span class="p">(</span><span class="nv">includeAlpha</span><span class="p">:</span> <span class="kt">Bool</span> <span class="o">=</span> <span class="kc">false</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">String</span><span class="p">?</span> <span class="p">{</span>
        <span class="k">var</span> <span class="nv">red</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">var</span> <span class="nv">green</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">var</span> <span class="nv">blue</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">var</span> <span class="nv">alpha</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span>

        <span class="k">guard</span> <span class="k">self</span><span class="o">.</span><span class="nf">getRed</span><span class="p">(</span><span class="o">&amp;</span><span class="n">red</span><span class="p">,</span> <span class="nv">green</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">green</span><span class="p">,</span> <span class="nv">blue</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">blue</span><span class="p">,</span> <span class="nv">alpha</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">alpha</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">return</span> <span class="kc">nil</span> <span class="c1">// 色をRGB空間で表現できませんでした</span>
        <span class="p">}</span>

        <span class="k">if</span> <span class="n">includeAlpha</span> <span class="p">{</span>
            <span class="k">return</span> <span class="kt">String</span><span class="p">(</span><span class="nv">format</span><span class="p">:</span> <span class="s">"#%02X%02X%02X%02X"</span><span class="p">,</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">red</span> <span class="o">*</span> <span class="mi">255</span><span class="p">),</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">green</span> <span class="o">*</span> <span class="mi">255</span><span class="p">),</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">blue</span> <span class="o">*</span> <span class="mi">255</span><span class="p">),</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">alpha</span> <span class="o">*</span> <span class="mi">255</span><span class="p">))</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">return</span> <span class="kt">String</span><span class="p">(</span><span class="nv">format</span><span class="p">:</span> <span class="s">"#%02X%02X%02X"</span><span class="p">,</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">red</span> <span class="o">*</span> <span class="mi">255</span><span class="p">),</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">green</span> <span class="o">*</span> <span class="mi">255</span><span class="p">),</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">blue</span> <span class="o">*</span> <span class="mi">255</span><span class="p">))</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>直接 UIColor に対して拡張（Extension）を行った後のアクセス方法は以下の通りです：</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">color</span> <span class="o">=</span> <span class="kt">UIColor</span><span class="o">.</span><span class="n">blue</span>
<span class="n">color</span><span class="o">.</span><span class="nf">toHexString</span><span class="p">()</span> <span class="c1">// #0000ff</span>
</code></pre></div></div>

<h4 id="問題">問題</h4>

<p>自分で定義した拡張が増えると、アクセスインターフェースが混乱し始めることがあります。例えば：</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">color</span> <span class="o">=</span> <span class="kt">UIColor</span><span class="o">.</span><span class="n">blue</span>
<span class="n">color</span><span class="o">.</span><span class="nf">getRed</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="n">color</span><span class="o">.</span><span class="nf">getWhite</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="n">color</span><span class="o">.</span><span class="nf">getHue</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="n">color</span><span class="o">.</span><span class="nf">getCMYK</span><span class="p">()</span> <span class="c1">// 自分で拡張したメソッド</span>
<span class="n">color</span><span class="o">.</span><span class="nf">toHexString</span><span class="p">()</span> <span class="c1">// 自分で拡張したメソッド</span>
<span class="n">color</span><span class="o">.</span><span class="nf">withAlphaComponent</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="n">color</span><span class="o">.</span><span class="nf">setFill</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="n">color</span><span class="o">.</span><span class="nf">setToBlue</span><span class="p">()</span> <span class="c1">// 自分で拡張したメソッド</span>

<span class="c1">// A モジュール</span>
<span class="kd">public</span> <span class="kd">extension</span> <span class="kt">UIColor</span> <span class="p">{</span>
  <span class="kd">func</span> <span class="nf">getCMYK</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// ...</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// B モジュール</span>
<span class="c1">// 'getCMYK()' の再宣言は無効です</span>
<span class="kd">public</span> <span class="kd">extension</span> <span class="kt">UIColor</span> <span class="p">{</span>
  <span class="kd">func</span> <span class="nf">getCMYK</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// ...</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>私たちが独自に拡張したメソッドとネイティブのメソッドがすべて混ざってしまい、区別が難しくなります。また、プロジェクトの規模が大きくなり、参照するライブラリが増えると、Extensionの命名衝突が発生する可能性があります。例えば、二つのライブラリが両方とも UIColor を拡張し、同じく <code class="language-plaintext highlighter-rouge">getCMYK()</code> と名付けた場合、問題が生じます。</p>

<h3 id="カスタム拡張-namespace-コンテナ">カスタム拡張 Namespace コンテナ</h3>

<p>SwiftのProtocol、計算プロパティ、ジェネリクスの特徴を活用して、拡張メソッドを自分でカプセル化し、Namespaceの機能を持たせることができます。</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// ジェネリックコンテナ ExtensionContainer&lt;Base&gt; を宣言：</span>
<span class="kd">public</span> <span class="kd">struct</span> <span class="kt">ExtensionContainer</span><span class="o">&lt;</span><span class="kt">Base</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="kd">public</span> <span class="k">let</span> <span class="nv">base</span><span class="p">:</span> <span class="kt">Base</span>
    <span class="kd">public</span> <span class="nf">init</span><span class="p">(</span><span class="n">_</span> <span class="nv">base</span><span class="p">:</span> <span class="kt">Base</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">base</span> <span class="o">=</span> <span class="n">base</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// AnyObject、クラス（参照）タイプ向けのプロトコルを定義：</span>
<span class="c1">// 例：Foundation の NSXXX クラス</span>
<span class="kd">public</span> <span class="kd">protocol</span> <span class="kt">ExtensionCompatibleObject</span><span class="p">:</span> <span class="kt">AnyObject</span> <span class="p">{}</span>
<span class="c1">// 構造体（値）タイプ向けのプロトコルを定義：</span>
<span class="kd">public</span> <span class="kd">protocol</span> <span class="kt">ExtensionCompatible</span> <span class="p">{}</span>

<span class="c1">// カスタム Namespace 計算プロパティ：</span>
<span class="kd">public</span> <span class="kd">extension</span> <span class="kt">ExtensionCompatibleObject</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">zhg</span><span class="p">:</span> <span class="kt">ExtensionContainer</span><span class="o">&lt;</span><span class="k">Self</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kt">ExtensionContainer</span><span class="p">(</span><span class="k">self</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">public</span> <span class="kd">extension</span> <span class="kt">ExtensionCompatible</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">zhg</span><span class="p">:</span> <span class="kt">ExtensionContainer</span><span class="o">&lt;</span><span class="k">Self</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kt">ExtensionContainer</span><span class="p">(</span><span class="k">self</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="ネイティブ型の拡張-1">ネイティブ型の拡張</h4>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">UIColor</span><span class="p">:</span> <span class="kt">ExtensionCompatibleObject</span> <span class="p">{}</span>

<span class="kd">extension</span> <span class="kt">ExtensionContainer</span> <span class="k">where</span> <span class="kt">Base</span><span class="p">:</span> <span class="kt">UIColor</span> <span class="p">{</span>
    <span class="c1">/// UIColorを16進数の文字列に変換します。</span>
    <span class="c1">/// - Returns: 16進数の文字列（例: "#RRGGBB" または "#RRGGBBAA"）。</span>
    <span class="kd">func</span> <span class="nf">toHexString</span><span class="p">(</span><span class="nv">includeAlpha</span><span class="p">:</span> <span class="kt">Bool</span> <span class="o">=</span> <span class="kc">false</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">String</span><span class="p">?</span> <span class="p">{</span>
        <span class="k">var</span> <span class="nv">red</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">var</span> <span class="nv">green</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">var</span> <span class="nv">blue</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">var</span> <span class="nv">alpha</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span>

        <span class="k">guard</span> <span class="k">self</span><span class="o">.</span><span class="n">base</span><span class="o">.</span><span class="nf">getRed</span><span class="p">(</span><span class="o">&amp;</span><span class="n">red</span><span class="p">,</span> <span class="nv">green</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">green</span><span class="p">,</span> <span class="nv">blue</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">blue</span><span class="p">,</span> <span class="nv">alpha</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">alpha</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">return</span> <span class="kc">nil</span> <span class="c1">// 色をRGB空間で表現できませんでした</span>
        <span class="p">}</span>

        <span class="k">if</span> <span class="n">includeAlpha</span> <span class="p">{</span>
            <span class="k">return</span> <span class="kt">String</span><span class="p">(</span><span class="nv">format</span><span class="p">:</span> <span class="s">"#%02X%02X%02X%02X"</span><span class="p">,</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">red</span> <span class="o">*</span> <span class="mi">255</span><span class="p">),</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">green</span> <span class="o">*</span> <span class="mi">255</span><span class="p">),</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">blue</span> <span class="o">*</span> <span class="mi">255</span><span class="p">),</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">alpha</span> <span class="o">*</span> <span class="mi">255</span><span class="p">))</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">return</span> <span class="kt">String</span><span class="p">(</span><span class="nv">format</span><span class="p">:</span> <span class="s">"#%02X%02X%02X"</span><span class="p">,</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">red</span> <span class="o">*</span> <span class="mi">255</span><span class="p">),</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">green</span> <span class="o">*</span> <span class="mi">255</span><span class="p">),</span>
                          <span class="kt">Int</span><span class="p">(</span><span class="n">blue</span> <span class="o">*</span> <span class="mi">255</span><span class="p">))</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="使用">使用</h4>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">color</span> <span class="o">=</span> <span class="kt">UIColor</span><span class="o">.</span><span class="n">blue</span>
<span class="n">color</span><span class="o">.</span><span class="n">zhg</span><span class="o">.</span><span class="nf">toHexString</span><span class="p">()</span> <span class="c1">// #0000ff</span>
</code></pre></div></div>

<h4 id="例2-urlのqueryitems拡張">例2. URLの.queryItems拡張</h4>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>extension URL: ExtensionCompatible {}

extension ExtensionContainer where Base == URL {
    
    var queryParameters: [String: String]? {
        URLComponents(url: base, resolvingAgainstBaseURL: true)?
            .queryItems?
            .reduce(into: [String: String]()) { $0[$1.name] = $1.value }
    }
}
let url = URL(string: "https://zhgchg.li?a=b&amp;c=d")!
url.zhg.queryParameters // ["c": "d", "a": "b"]
</code></pre></div></div>

<h3 id="builder-pattern-の統合"><a href="https://refactoring.guru/design-patterns/builder" target="_blank">Builder Pattern</a> の統合</h3>

<p>また、このラッピング方法を Builder Pattern と組み合わせて操作することもできます：</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kd">class</span> <span class="kt">URLBuilder</span> <span class="p">{</span>
    <span class="kd">private</span> <span class="k">var</span> <span class="nv">components</span><span class="p">:</span> <span class="kt">URLComponents</span>

    <span class="nf">init</span><span class="p">(</span><span class="nv">base</span><span class="p">:</span> <span class="kt">URL</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">components</span> <span class="o">=</span> <span class="kt">URLComponents</span><span class="p">(</span><span class="nv">url</span><span class="p">:</span> <span class="n">base</span><span class="p">,</span> <span class="nv">resolvingAgainstBaseURL</span><span class="p">:</span> <span class="kc">true</span><span class="p">)</span><span class="o">!</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">setQueryParameters</span><span class="p">(</span><span class="n">_</span> <span class="nv">parameters</span><span class="p">:</span> <span class="p">[</span><span class="kt">String</span><span class="p">:</span> <span class="kt">String</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="kt">URLBuilder</span> <span class="p">{</span>
        <span class="n">components</span><span class="o">.</span><span class="n">queryItems</span> <span class="o">=</span> <span class="n">parameters</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="nv">$0</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="nv">value</span><span class="p">:</span> <span class="nv">$0</span><span class="o">.</span><span class="n">value</span><span class="p">)</span> <span class="p">}</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">setScheme</span><span class="p">(</span><span class="n">_</span> <span class="nv">scheme</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">URLBuilder</span> <span class="p">{</span>
        <span class="n">components</span><span class="o">.</span><span class="n">scheme</span> <span class="o">=</span> <span class="n">scheme</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">build</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">URL</span><span class="p">?</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">components</span><span class="o">.</span><span class="n">url</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">URL</span><span class="p">:</span> <span class="kt">ExtensionCompatible</span> <span class="p">{}</span>

<span class="kd">extension</span> <span class="kt">ExtensionContainer</span> <span class="k">where</span> <span class="kt">Base</span> <span class="o">==</span> <span class="kt">URL</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">builder</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">URLBuilder</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kt">URLBuilder</span><span class="p">(</span><span class="nv">base</span><span class="p">:</span> <span class="n">base</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">let</span> <span class="nv">url</span> <span class="o">=</span> <span class="kt">URL</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="s">"https://zhgchg.li"</span><span class="p">)</span><span class="o">!.</span><span class="n">zhg</span><span class="o">.</span><span class="nf">builder</span><span class="p">()</span><span class="o">.</span><span class="nf">setQueryParameters</span><span class="p">([</span><span class="s">"a"</span><span class="p">:</span> <span class="s">"b"</span><span class="p">,</span> <span class="s">"c"</span><span class="p">:</span> <span class="s">"d"</span><span class="p">])</span><span class="o">.</span><span class="nf">setScheme</span><span class="p">(</span><span class="s">"ssh"</span><span class="p">)</span><span class="o">.</span><span class="nf">build</span><span class="p">()</span>
<span class="c1">// ssh://zhgchg.li?a=b&amp;c=d</span>
</code></pre></div></div>

<p><em><a href="https://medium.com/zrealm-ios-dev/swift-%E4%B8%80%E5%80%8B%E5%84%AA%E9%9B%85%E7%9A%84%E5%8E%9F%E7%94%9F%E9%A1%9E%E5%9E%8B%E6%93%B4%E5%B1%95%E6%96%B9%E5%BC%8F-a8925ad9ed01" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>によって変換されました。</em></p>]]></content>
  </entry><entry>
    <title type="html">山陰島根出雲松江鳥取関西7日自由行｜交通1000km・歩数10万歩の旅程ガイド</title>
    <link href="https://jp.zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E5%B1%B1%E9%99%B0%E5%B3%B6%E6%A0%B9%E5%87%BA%E9%9B%B2%E6%9D%BE%E6%B1%9F%E9%B3%A5%E5%8F%96%E9%96%A2%E8%A5%BF7%E6%97%A5%E8%87%AA%E7%94%B1%E8%A1%8C-%E4%BA%A4%E9%80%9A1000km-%E6%AD%A9%E6%95%B010%E4%B8%87%E6%AD%A9%E3%81%AE%E6%97%85%E7%A8%8B%E3%82%AC%E3%82%A4%E3%83%89-aacd5f5cacd1/" rel="alternate" type="text/html" title="山陰島根出雲松江鳥取関西7日自由行｜交通1000km・歩数10万歩の旅程ガイド" />
    <published>2024-12-03T00:04:56+08:00</published>
    <updated>2025-08-13T13:38:47+08:00</updated>
    <id>https://jp.zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/aacd5f5cacd1</id><summary type="html">岡山発着で山陰の出雲・松江、鳥取を巡り、姫路・大阪・神戸へ。7日間で1,000km移動、10万歩歩く自由旅行プランを詳解。効率的な交通ルートと観光スポットを網羅し、充実した旅を実現します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="Z 度旅行遊記" /><category term="生活" /><category term="日本" /><category term="旅行記" /><category term="島根県" /><category term="旅行" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/aacd5f5cacd1/1*ucEUq8avIv1nBoNnCMlgRw.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/z-%E5%BA%A6%E6%97%85%E8%A1%8C%E9%81%8A%E8%A8%98/%E5%B1%B1%E9%99%B0%E5%B3%B6%E6%A0%B9%E5%87%BA%E9%9B%B2%E6%9D%BE%E6%B1%9F%E9%B3%A5%E5%8F%96%E9%96%A2%E8%A5%BF7%E6%97%A5%E8%87%AA%E7%94%B1%E8%A1%8C-%E4%BA%A4%E9%80%9A1000km-%E6%AD%A9%E6%95%B010%E4%B8%87%E6%AD%A9%E3%81%AE%E6%97%85%E7%A8%8B%E3%82%AC%E3%82%A4%E3%83%89-aacd5f5cacd1/"><![CDATA[<h3 id="旅行記-2024年-山陰広域エリア-島根-出雲-松江-鳥取-姫路-大阪-神戸-7日間一人旅自由行">[旅行記] 2024年 山陰広域エリア 島根 出雲 松江 鳥取 姫路 大阪 神戸 7日間一人旅自由行</h3>

<p>岡山から入出、まず山陰の島根県出雲・松江へ、その後鳥取へ行き、最後に姫路・関西・大阪へ戻る。7日間で10万歩、交通距離は1,000キロを超え、山陰・関西エリアを一度に巡る。</p>

<p><img src="/assets/aacd5f5cacd1/1*ucEUq8avIv1nBoNnCMlgRw.webp" alt="宍道湖の夕日" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*ucEUq8avIv1nBoNnCMlgRw.jpeg" /></p>

<p>宍道湖の夕日</p>

<h4 id="はじめに">はじめに</h4>

<p>最初、2024年下半期は仙台に行こうと思っていましたが、観光地の情報を調べたところ、この時期の興味はあまり湧きませんでした。去年の同じ週、11/13–18に<strong>「<a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/">山陽地区 広島岡山 6日間自由旅行</a>」</strong>に行って、中国地方、山陽、岡山の印象がとても良かったことを思い出しました — 景色が美しく、交通も便利で、観光客も少なめでした。そこで今回は山陰地区（島根、鳥取）も巡ろうと思い、ちょうど仕事の合間もあり、最近気分転換が急務だったため、この7日間6泊の山陰地区（加えて関西地区：姫路、大阪）一人旅自由旅行が実現しました。</p>

<h3 id="準備作業">準備作業</h3>

<h4 id="日付111218">日付：11/12–18</h4>

<p>今回はまたP人の発作で、10月中旬に急に時間ができたため、すぐに11月12日出発、11月18日帰国の予定を立てました。</p>

<h4 id="️航空券">✈️航空券</h4>

<p><img src="/assets/aacd5f5cacd1/1*XRfz2GcB_EiuvwxLYIFCTw.webp" alt="" loading="lazy" decoding="async" width="1189" height="580" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTg5IiBoZWlnaHQ9IjU4MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*XRfz2GcB_EiuvwxLYIFCTw.png" /></p>

<p>今年は特にタイガーエアの秋のセールでチケットを取らなかったが、<strong>去年はお得なチケットを購入できた</strong>。時間も良く、価格も安かった（<code class="language-plaintext highlighter-rouge">去年：往路(11:10)、復路(15:25)、往復20KGの受託手荷物＋座席指定＋諸費用込み：NT$ 7,012</code>）。</p>

<ul>
  <li>
    <p>行き：13:05 TPE 台北桃園国際空港 -&gt; <strong>16:30 OKJ</strong> 岡山桃太郎空港</p>
  </li>
  <li>
    <p>帰り：<strong>17:30 OKJ</strong> 岡山桃太郎空港 -&gt; 19:35 TPE 台北桃園国際空港</p>
  </li>
  <li>
    <p>往復20KG手荷物＋座席指定＋諸費用の価格：<code class="language-plaintext highlighter-rouge">NT$ 9,118</code></p>
  </li>
</ul>

<p>特に安くはないですが、許容範囲です。去年と同じ往復時間を選ぶともっと高くなり、だいたい <code class="language-plaintext highlighter-rouge">NT$ 12,000</code> くらいになります。</p>

<h4 id="虎航-2025年-新直行便">虎航 2025年 新直行便</h4>

<p><a href="https://chugoku.letsgojp.com/archives/731900" target="_blank">台湾虎航は2025年5月29日（木）から「桃園国際空港－鳥取米子空港」直行便を新たに運航開始し、山陰地方へのアクセスがさらに便利になります！</a></p>

<h4 id="️計画">🏝️計画</h4>

<p>山陰地方と姫路には行ったことがなく、この三つの場所を中心にしました。</p>

<ul>
  <li>
    <p>11/12 夜に岡山に到着し、一泊します。翌朝の島根行きに備えます。</p>
  </li>
  <li>
    <p>11/13 朝早くJRで島根へ向かい、まず出雲大社と稲佐の浜へ行きます。午後から夕方にかけて宍道湖で夕日を見ます。</p>
  </li>
  <li>
    <p>11/14 午前に松江城と松江堀川遊覧船、午後に足立美術館、夜に鳥取に到着。</p>
  </li>
  <li>
    <p>11/15 午前は白兎神社、午後は鳥取砂丘、夜に姫路に到着。</p>
  </li>
  <li>
    <p>11/16 姫路城、姫路市内散策<br />
実際に訪れた場所：書写山円教寺。</p>
  </li>
  <li>
    <p>11/17 大鳴門橋遊歩道 渦の道、鳴門の渦潮、明石海峡大橋<br />
実際には天候不良のため行かず、大阪・神戸で買い物と食事をしました。</p>
  </li>
  <li>
    <p>11/18 岡山駅でショッピング、帰路。</p>
  </li>
</ul>

<h4 id="移動---日本-jr-pass関西山陰エリア鉄道周遊券emco電子チケット">🚅移動 - <a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank"><strong>日本 JR PASS｜関西＆山陰エリア鉄道周遊券｜eMCO電子チケット</strong></a></h4>

<p>今回は長距離移動なので、必ずJRパスを買うべきです。最初は山陰・山陽のJRパスだけかと思っていましたが、日本のJRはとても親切で、可能なルートをすべて計画してくれて、「<a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank"><strong>関西＆山陰エリア鉄道周遊券 JRPass</strong></a>」がまさに私の希望にぴったりでした！</p>

<p><img src="/assets/aacd5f5cacd1/1*H0ztJ3sX7oPQmJz7L2j87w.webp" alt="関西＆山陰エリア鉄道周遊券 JRPass 利用範囲" loading="lazy" decoding="async" width="1330" height="1080" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzMwIiBoZWlnaHQ9IjEwODAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*H0ztJ3sX7oPQmJz7L2j87w.png" /></p>

<p><a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank">関西＆山陰エリア鉄道周遊券 JRPass 利用範囲</a></p>

<ul>
  <li>価格：<code class="language-plaintext highlighter-rouge">NT$ 3,779</code> さらにもう1枚プレゼント <a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank"><strong>山陰山陽エリアパス3日券（組み合わせて使うととてもお得）</strong></a></li>
</ul>

<h4 id="ネット環境">📱ネット環境</h4>

<p>今回はKKdayから「<a href="https://www.kkday.com/zh-tw/product/137689-japan-high-speed-daily-unlimited-data-japanese-esim?cid=19365" target="_blank"><strong>日本eSIMカード｜毎日高速、総量、無制限データ使い放題プラン｜65%オフ</strong></a>」も一緒に購入しました。</p>

<ul>
  <li>
    <p>7日間 無制限データ通信 eSIMプラン</p>
  </li>
  <li>
    <p>価格： <code class="language-plaintext highlighter-rouge">NT$ 847</code></p>
  </li>
</ul>

<p>実際に使ってみて、とても安定しており、速度制限や切断の問題はありませんでした。</p>

<blockquote>
  <p><em>eSIMの有効化方法と注意点は本文に記載していますので、引き続きお読みください。</em></p>
</blockquote>

<h4 id="日本円">日本円</h4>

<p><img src="/assets/aacd5f5cacd1/1*ljW0bI5fjkI2Xasi4KvA5A.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ljW0bI5fjkI2Xasi4KvA5A.jpeg" /></p>

<p>新しい日本円の紙幣に交換しました。</p>

<blockquote>
  <p><em>新札と旧札の両方を少し持っていくことをおすすめします。一部の自動販売機では新札が使えません。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*_Zz6O5dhksVtJvi8TqN1yw.webp" alt="新札も使える自動販売機" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_Zz6O5dhksVtJvi8TqN1yw.jpeg" /></p>

<p>新しいお札が使える自動販売機</p>

<h4 id="宿泊施設">🏠宿泊施設</h4>

<p>今回は幸運にも松江での一泊だけ<a href="https://www.toyoko-inn.com/china/index2" target="_blank">東横イン</a>が取れませんでしたが、他はすべて予約できました。</p>

<p><strong>11/12 <a href="https://www.toyoko-inn.com/china/search/detail/00232/" target="_blank">東横INN 岡山駅東口</a> (一泊)</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*Kidzn6hm372657rCN8jTgw.webp" alt="岡山駅から徒歩4分で到着" loading="lazy" decoding="async" width="620" height="289" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MjAiIGhlaWdodD0iMjg5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*Kidzn6hm372657rCN8jTgw.png" /></p>

<p>岡山駅から徒歩4分です。</p>

<ul>
  <li>
    <p>禁煙ツインルーム、宿泊人数：1名</p>
  </li>
  <li>
    <p>価格： <code class="language-plaintext highlighter-rouge">NT$ 1,616</code></p>
  </li>
</ul>

<p><strong>11/13 <a href="https://www.station.matsue-urban.co.jp/en/" target="_blank">松江アーバンホテル</a>（一泊）</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*9QIJ7lY1W7L94dgKGm6VQQ.webp" alt="松江駅を出て2分歩くと到着します" loading="lazy" decoding="async" width="413" height="287" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MTMiIGhlaWdodD0iMjg3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*9QIJ7lY1W7L94dgKGm6VQQ.png" /></p>

<p>松江駅を出てから徒歩2分で到着します。</p>

<ul>
  <li>
    <p>ダブルルーム（セミダブルベッド）— 禁煙 — 2号館<br />
宿泊者：1名</p>
  </li>
  <li>
    <p>価格： <code class="language-plaintext highlighter-rouge">NT$ 2,431</code></p>
  </li>
</ul>

<p><strong>11/14 <a href="https://www.toyoko-inn.com/china/search/detail/00046/" target="_blank">東横INN 鳥取駅南口</a> (一泊)</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*hIqnM7MaRDWsRoRsydTqCg.webp" alt="鳥取駅を出て4分歩くと到着" loading="lazy" decoding="async" width="587" height="373" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1ODciIGhlaWdodD0iMzczIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*hIqnM7MaRDWsRoRsydTqCg.png" /></p>

<p>鳥取駅を出て徒歩4分で到着します。</p>

<ul>
  <li>
    <p>禁煙ダブルルーム、宿泊人数：1名</p>
  </li>
  <li>
    <p>価格： <code class="language-plaintext highlighter-rouge">NT$ 1,595</code></p>
  </li>
</ul>

<p><strong>11/15 <a href="https://www.toyoko-inn.com/china/search/detail/00317/" target="_blank">東横INN 姫路駅新幹線北口</a> (3泊)</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*P4xut5p60ZVSDtPkpoO6Pw.webp" alt="姫路駅から徒歩5分で到着" loading="lazy" decoding="async" width="777" height="591" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzciIGhlaWdodD0iNTkxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*P4xut5p60ZVSDtPkpoO6Pw.png" /></p>

<p>姫路駅を出てから徒歩5分で到着します。</p>

<ul>
  <li>
    <p>禁煙ダブルルーム、宿泊人数：1名</p>
  </li>
  <li>
    <p>価格： <code class="language-plaintext highlighter-rouge">NT$ 6,055</code> 、 <code class="language-plaintext highlighter-rouge">NT$ 2,018</code> /泊</p>
  </li>
</ul>

<p>ほとんど東横インを予約できましたが、予約が遅かったためシングルルームはなくツインルームしか空いておらず、一泊の料金が高くなりました。もしシングルルームが取れれば、一泊約<code class="language-plaintext highlighter-rouge">NT$ 1,500</code>以内に抑えられたと思います。ただ、過去の経験から、日程が近づくとツインルームも満室になることが多く、場所的にあまり人が行かないのかもしれません。</p>

<blockquote>
  <p><em>部屋の紹介動画は本文中に掲載しますので、引き続きお読みください。</em></p>
</blockquote>

<p>—</p>

<blockquote>
  <p><a href="/posts/z-度旅行遊記/京阪神自由行-8日間の京都-大阪-神戸旅行完全ガイド-食事-宿泊-交通情報を網羅-76d66c2e34af/"><em>Flight Tracker、iPhone Suicaの利用、Visit Japan事前入国申請については、以前の記事で触れているため、ここでは詳しく説明しません。</em></a></p>
</blockquote>

<blockquote>
  <p><em><a href="http://vjw.digital.go.jp/" target="_blank">Visit Japan</a> <strong>以前と違うのは「入国審査」と「税関申告」のQRコードが一つに統合され、「入国審査および税関申告のQRコード」となり、青コードと黄コードの区別がなくなったことだけです。</strong></em></p>
</blockquote>

<h4 id="tigerair-オンラインセルフチェックイン">Tigerair オンラインセルフチェックイン</h4>

<p>出発の1〜3日前に、タイガーエアから旅程通知メールが届きます。<strong>必ず！必ず！必ず！</strong> 出発前にオンラインの「セルフチェックイン」を完了してください：</p>

<p><img src="/assets/aacd5f5cacd1/1*3K4biik6RnLXrqp453siiA.webp" alt="" loading="lazy" decoding="async" width="1120" height="1153" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTIwIiBoZWlnaHQ9IjExNTMiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*3K4biik6RnLXrqp453siiA.png" /></p>

<p>セルフチェックインをクリックすると、Tigerairの公式サイトに移動し、乗客情報と手荷物の安全確認を行い、最後に「搭乗券」が発行され、送付されます。</p>

<p><img src="/assets/aacd5f5cacd1/1*oupKW1tFwXdEwj4pEAL8hw.webp" alt="" loading="lazy" decoding="async" width="511" height="846" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTEiIGhlaWdodD0iODQ2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*oupKW1tFwXdEwj4pEAL8hw.png" /></p>

<p>搭乗券を大切に保管し、これを持って空港へ行けば「手荷物セルフチェックイン」で直接荷物を預けることができ、長い「一般チェックイン」カウンターに並ぶ時間を節約できます。</p>

<h4 id="さあ行こう-出発">さあ行こう 出発！</h4>

<h4 id="kkday-プロモーション-">KKday プロモーション 🛒</h4>

<ul>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/153331" target="_blank">日本 JR PASS\|鳥取・松江エリア周遊券\|eMCO 電子チケット</a>
（松江、鳥取松江エリアのみ訪れる場合におすすめ）</p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank"><strong>関西＆山陰エリア鉄道周遊券 JRPass</strong></a>
（岡山空港発着に最適な選択）</p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/137689-japan-high-speed-daily-unlimited-data-japanese-esim?cid=19365" target="_blank"><strong>日本eSIMカード｜毎日高速、総量、無制限データ使い放題プラン</strong></a></p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/20315-jr-sanyo-sanin-area-pass?cid=19365" target="_blank">日本 JR PASS｜山陽＆山陰エリア鉄道周遊券｜eMCO 電子チケット</a>
（一気に山陽山陰エリアを満喫）</p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/184144?cid=19365" target="_blank">鳥取砂丘 \| 日本唯一のスリリングな砂滑り体験</a></p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/11463-osaka-bus-tour-tottori-sand-dunes-uratomi-coast-cruise-sand-museum-japan?cid=19365" target="_blank">【鳥取バス日帰りツアー】鳥取砂丘、浦富海岸クルーズ、砂の美術館、梨狩り体験｜特色ランチ付き（大阪発）</a></p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/262558?cid=19365" target="_blank">鳥取砂丘と有名な出雲大社を巡る2日間バスツアー（大阪発）</a></p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/185589?cid=19365" target="_blank">新年参拝！出雲大社3時間滞在【広島発】</a></p>
  </li>
</ul>

<h3 id="1日目1112-火曜日出発">1日目（11/12 火曜日）出発</h3>

<p>午後13:05の飛行機なので、朝8時に起きて9時頃に出発しても時間に余裕があります。</p>

<p><img src="/assets/aacd5f5cacd1/1*LyhBB17WajIUYryRUrIgaA.webp" alt="2024/11 事前チェックイン公式サイトより" loading="lazy" decoding="async" width="546" height="338" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NDYiIGhlaWdodD0iMzM4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*LyhBB17WajIUYryRUrIgaA.png" /></p>

<p><a href="https://www.taoyuan-airport.com/ITCI/index.html" target="_blank">2024/11 事前チェックイン公式サイトより</a></p>

<p>虎航 <a href="https://www.taoyuan-airport.com/ITCI/index.html" target="_blank"><strong>事前チェックインサービス（MRTでチェックイン＋荷物預け、空港で直接出国）</strong></a> は <strong>MRT A3 新北産業園区駅</strong> 限定で利用可能です。台北駅では利用できないため、そのままMRT直達列車で第一ターミナルへ向かいました。</p>

<h4 id="-1000-空港到着">~= 10:00 空港到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*4_ZTToEL1W6fwNWpo_GvBw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*4_ZTToEL1W6fwNWpo_GvBw.jpeg" /></p>

<p>約10:00に空港に到着し、カウンターは10:20からオープンします。</p>

<h4 id="-1020-手荷物セルフチェックインで荷物を預ける予約">~= 10:20 「手荷物セルフチェックイン」で荷物を預ける予約</h4>

<p><img src="/assets/aacd5f5cacd1/1*4y0Kgdbk8bbcUgajmi27IQ.webp" alt="" loading="lazy" decoding="async" width="951" height="1238" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTEiIGhlaWdodD0iMTIzOCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4y0Kgdbk8bbcUgajmi27IQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*5_TKj5PZ-iUMi3r3CqrmzA.webp" alt="行き：9 KG" loading="lazy" decoding="async" width="611" height="776" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MTEiIGhlaWdodD0iNzc2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*5_TKj5PZ-iUMi3r3CqrmzA.png" /></p>

<p>往路：9 KG</p>

<p>この時、まずタイガーエアのウェブチェックインの利点が活きました。当日、現地の「一般チェックイン」カウンターは長蛇の列で、10:20にはすでに満員で、少なくとも45分から1時間待つ見込みでした。「手荷物セルフチェックイン」は約15分以内で手続きが完了し、大幅に待ち時間を節約できました。</p>

<blockquote>
  <p><em>現地でオンラインチェックインを済ませてから「手荷物セルフ預け機」に並ぶ方が、「通常のチェックインカウンター」に並ぶよりずっと早いです。</em></p>
</blockquote>

<h4 id="-1050-出国手続き完了">~= 10:50 出国手続き完了</h4>

<p><img src="/assets/aacd5f5cacd1/1*aD3atJOMZWAhStzpdoaZDg.webp" alt="" loading="lazy" decoding="async" width="937" height="1167" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzciIGhlaWdodD0iMTE2NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*aD3atJOMZWAhStzpdoaZDg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*OLORgiz8R6pOfG-m9P-aOw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OLORgiz8R6pOfG-m9P-aOw.jpeg" /></p>

<p>今回は第一ターミナルのA1搭乗口です。（ようやくバスに乗らなくて済みました）</p>

<p><img src="/assets/aacd5f5cacd1/1*MDpHGgVgU0QRH0BGFmzLbA.webp" alt="" loading="lazy" decoding="async" width="951" height="1236" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTEiIGhlaWdodD0iMTIzNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*MDpHGgVgU0QRH0BGFmzLbA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ZU4N6uWzEYhp_J2C3JE0Dg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1034" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMzQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*ZU4N6uWzEYhp_J2C3JE0Dg.png" /></p>

<p>以前、第一ターミナルに来るたびに頂呱呱を食べていましたが、今回は老董牛肉麺に変えました。お店はA1搭乗口の近くにあり、とても便利な場所です。</p>

<h4 id="-1130-搭乗待ち">~= 11:30 搭乗待ち</h4>

<p><img src="/assets/aacd5f5cacd1/1*Xaux1WjOTpXcqxeF1-UlXw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*Xaux1WjOTpXcqxeF1-UlXw.jpeg" /></p>

<p>お腹がいっぱいでぶらぶらしていたら、だいたい11:30頃、A1搭乗口の欠点は<a href="/posts/z-度旅行記/九州自由行-釜山発博多入国の郵輪旅で由布院-大分-福岡を満喫-cb65fd5ab770/"><strong>一航無料ラウンジ</strong></a>から遠いことです。歩き回るのが面倒だったので、そのまま搭乗待合室に来ました。</p>

<p>事前に2つのネットワーク問題を対処しました。まず、私の<a href="https://123.cht.com.tw/IVRredir/" target="_blank"><strong>中華電信のローミング機能はオフになっています</strong></a>ので、ローミングプランを直接購入できません。そのため、念のために中華電信へ電話してローミング機能を解除してもらいました。</p>

<p><img src="/assets/aacd5f5cacd1/1*dF9XuqFK3bW2X249DYtqZg.webp" alt="中華電信に電話し、本人確認後にカスタマーサポートへロック解除を依頼してください。" loading="lazy" decoding="async" width="574" height="1206" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NzQiIGhlaWdodD0iMTIwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*dF9XuqFK3bW2X249DYtqZg.png" /></p>

<p>中華電信に電話し、本人確認の後にカスタマーサポートにロック解除を依頼してください。</p>

<h4 id="事前にesimを有効化するiphoneの場合">事前にeSIMを有効化する（iPhoneの場合）</h4>

<p>二つ目のネットワーク問題は、空港でeSIMを有効化する際に、eSIMの入力と有効化にはネット接続が必要なため、岡山空港のWiFiが不安定だと心配したことです。そのため、事前に台湾で安定したネット環境のもとで日本のeSIMを有効化しました。</p>

<blockquote>
  <p><em>もしネット環境が心配で入国に不安がある場合は、<strong>入国用QRコードをスクリーンショット</strong>するか、紙の入国カードに記入しておくと、二重の安心になります。</em></p>
</blockquote>

<p>以前タイで購入したeSIMは、購入証明メールやPDF、スクリーンショットのQRコードを長押しすると「eSIMを追加」が表示され、自動で追加できましたが、今回購入した日本のeSIMでは表示されませんでした：</p>

<p><img src="/assets/aacd5f5cacd1/1*su5YVQrLdjFXORHuiMZxuw.webp" alt="" loading="lazy" decoding="async" width="567" height="1013" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjciIGhlaWdodD0iMTAxMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*su5YVQrLdjFXORHuiMZxuw.png" /></p>

<p><strong><a href="https://www.ptt.cc/bbs/iOS/M.1719797706.A.916.html" target="_blank">ネットユーザー提供</a> の方法で「eSIMを追加」オプションが表示されることを確認しました。（iOSのバグのようで、iOS 17.4以降は動作しなくなりました）：</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*DrYXYUfGj_BddPe8FwbM4A.webp" alt="" loading="lazy" decoding="async" width="578" height="1047" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NzgiIGhlaWdodD0iMTA0NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*DrYXYUfGj_BddPe8FwbM4A.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Z-Ls2JPUbJAw93L7ey91gw.webp" alt="" loading="lazy" decoding="async" width="569" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjkiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Z-Ls2JPUbJAw93L7ey91gw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*BwNRm45uuwJcWjnYicDIEA.webp" alt="" loading="lazy" decoding="async" width="562" height="1151" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjIiIGhlaWdodD0iMTE1MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*BwNRm45uuwJcWjnYicDIEA.png" /></p>

<ol>
  <li>
    <p>eSIMの認証メールやPDFを開き、スマホでスクリーンショットを撮って写真アルバムに保存してください。</p>
  </li>
  <li>
    <p>スマホのカメラを開き、左下のアイコンをタップしてアルバムに入ります。</p>
  </li>
  <li>
    <p>アルバムでeSIMの写真を見つけ、QRコードを長押しすると「eSIMを追加」オプションが表示されます。</p>
  </li>
  <li>
    <p>「eSIMを追加」をタップすると、アクティベーション情報が自動で入力され、eSIMが有効になります。</p>
  </li>
</ol>

<h4 id="iphoneでesimを手動で有効にする">iPhoneでeSIMを手動で有効にする</h4>

<p><strong>「設定」→「モバイル通信」→「eSIMを追加」→「モバイル通信プランをQRコードで追加」へ進む：</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*TUIEbNDhczwvTehfFza_sg.webp" alt="" loading="lazy" decoding="async" width="562" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*TUIEbNDhczwvTehfFza_sg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*7hYiMadhEnU5NOt58ashJw.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*7hYiMadhEnU5NOt58ashJw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YUjZUpfB6BeLQKNWTMx-5A.webp" alt="" loading="lazy" decoding="async" width="581" height="1239" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1ODEiIGhlaWdodD0iMTIzOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YUjZUpfB6BeLQKNWTMx-5A.png" /></p>

<p>eSIMのQRコードを印刷してあるので、そこから直接スキャンして有効化しました。</p>

<p>もし何もない場合は、「手動で詳細情報を入力」をクリックして、eSIM証明書情報をコピー＆ペーストして手動で有効化してください：</p>

<p><img src="/assets/aacd5f5cacd1/1*TdmMDosao98OATMJNa0NLw.webp" alt="" loading="lazy" decoding="async" width="1200" height="1170" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjExNzAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*TdmMDosao98OATMJNa0NLw.png" /></p>

<p>メールの内容に従って <code class="language-plaintext highlighter-rouge">SM-DP+ アドレス</code>、<code class="language-plaintext highlighter-rouge">アクティベーションコード</code>、<code class="language-plaintext highlighter-rouge">確認コード</code>（今回はなし）を入力し、次へを押してアクティベーションを完了します。</p>

<p><img src="/assets/aacd5f5cacd1/1*cXjnkvYvDGnE-ByT3hcnaw.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*cXjnkvYvDGnE-ByT3hcnaw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*sc6xr-nA3J_BdYMcNBNMFA.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*sc6xr-nA3J_BdYMcNBNMFA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Rh7hWbEiUtLbR3VYXq9NOw.webp" alt="" loading="lazy" decoding="async" width="581" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1ODEiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Rh7hWbEiUtLbR3VYXq9NOw.png" /></p>

<p>入力完了後、アクティベートに少し時間がかかることがあります。「アクティベート中…」のまましばらく待つか、「アクティベート失敗、後で再試行してください」と表示される場合もありますが、少し待てば問題ありません。アクティベートが成功すると、「設定」→「モバイル通信」に「オン」と表示され、右上の信号アイコンの下に信号状況が表示されます。</p>

<ul>
  <li>行動プランのタグは「旅行」を選択できます。</li>
</ul>

<blockquote>
  <p><strong><em>私たちはまだ台湾にいるため、現時点では日本のeSIMネットワークに接続できません。起動が成功したことを確認するだけで問題ありません。</em></strong></p>
</blockquote>

<h4 id="-1220-搭乗開始遅延なし">~= 12:20 搭乗開始、遅延なし</h4>

<p><img src="/assets/aacd5f5cacd1/1*R1I1UY831lnjto_6jqwCFw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*R1I1UY831lnjto_6jqwCFw.jpeg" /></p>

<h4 id="-1305-定刻出発">~= 13:05 定刻出発</h4>

<p><img src="/assets/aacd5f5cacd1/1*ovXkaMS4yzLWpm2_YBTPFw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ovXkaMS4yzLWpm2_YBTPFw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*IQ1kIFLjFgrYHUqulJMO7Q.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*IQ1kIFLjFgrYHUqulJMO7Q.jpeg" /></p>

<p>この時、台湾では大雨が降り始めましたが、風はあまり強くなく、離陸にはほとんど影響がありませんでした。</p>

<p><img src="/assets/aacd5f5cacd1/1*Ooxdur72IKkRc4u5q52esQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*Ooxdur72IKkRc4u5q52esQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ECU47qVPUd7cv6UcBy6i3Q.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ECU47qVPUd7cv6UcBy6i3Q.jpeg" /></p>

<p>虎航の座席の快適さは、格安航空会社の中では優れていると思います（ピーチは狭すぎて、ベトジェットの椅子は座り心地が悪いのに比べて）。ただし、虎航の欠点は<a href="https://www.threads.net/@kechi.syonen/post/DCYnEQNzU5L/%E4%BB%80%E9%BA%BC%E8%83%BD%E5%B8%B6%E4%B8%8A%E9%A3%9B%E6%A9%9F%E4%BB%80%E9%BA%BC%E4%B8%8D%E8%83%BD%E5%B8%B6%E5%BE%88%E6%B8%85%E6%A5%9A%E4%BB%99%E5%8F%B0%E6%A9%9F%E5%A0%B4" target="_blank"><strong>持ち込み食べ物禁止</strong></a> 、満腹の時は問題なし！</p>

<p>機内にWiFiがなく、音楽を聴いたりオフラインゲームをしたりするだけです。</p>

<p><img src="/assets/aacd5f5cacd1/1*LaNvJoYfPvU3LJchfvJHlg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*LaNvJoYfPvU3LJchfvJHlg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*B5bSSUIBkoDGo147pFsEVQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*B5bSSUIBkoDGo147pFsEVQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*9Ibz55I3hZC0C7lSO-4o1A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*9Ibz55I3hZC0C7lSO-4o1A.jpeg" /></p>

<p>窓の外から日本の天気がとても良いのが見えます。👍👍👍</p>

<h4 id="1630台湾時間-1530定刻着陸">16:30（台湾時間 15:30）定刻着陸</h4>

<p><img src="/assets/aacd5f5cacd1/1*paerDziYhfHNdjAg1QeJBg.webp" alt="" loading="lazy" decoding="async" width="532" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MzIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*paerDziYhfHNdjAg1QeJBg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*y36b_kkD7RMz1R501bPkIw.webp" alt="" loading="lazy" decoding="async" width="566" height="1267" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjYiIGhlaWdodD0iMTI2NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*y36b_kkD7RMz1R501bPkIw.png" /></p>

<p>日本に到着した後、私たちの日本用eSIMはすぐに電波を受信できるはずです。</p>

<blockquote>
  <p><em>電波はあるがまだインターネットに接続できない場合は、「設定」-&gt;「モバイル通信」-&gt; <strong>旅遊 日本 eSIM</strong> を選択し、「この番号を有効にする」と <strong>データローミングをオンにする</strong> を確認してください。これでネット接続が可能になります！⚠️⚠️⚠️</em></p>
</blockquote>

<blockquote>
  <p><em>また、<strong>主要な中華電信</strong>の番号にもアクセスできます。中華電信のローミングプランを購入していない場合は、<strong>ここで「データローミング」をオフにし、「この番号をオンにする」をオンのままにしてください。これで台湾のSMSを受信できます！</strong></em></p>
</blockquote>

<blockquote>
  <p><strong><em>ご注意：不明な電話には出ないでください。海外から国内への着信は受信側にも料金が発生します！⚠️⚠️⚠️（SMSのみ無料）</em></strong></p>
</blockquote>

<h4 id="-1700-入国手続き完了荷物受取">~= 17:00 入国手続き完了、荷物受取</h4>

<ul>
  <li>
    <p>岡山桃太郎空港は非常に小さな空港で、国際便は今回の便のみです。同じ便の乗客と一緒に入国審査や荷物受取を行うため、とてもスムーズです。<br />
（今回の便はほぼ満席で、約30分で出口に出られました）</p>
  </li>
  <li>
    <p>意外だったのは、空港のスタッフが皆中国語を話せたことです。</p>
  </li>
  <li>
    <p>小さな空港は規則が厳しいのか、私のような一人旅の場合、ほとんど「何日間滞在しますか？」「どこに行きますか？」と聞かれます。中にはホテルの予約確認書の提示を求められることもあります。<br />
（そのため、個人旅行の場合は事前に準備しておくことをおすすめします）</p>
  </li>
</ul>

<h4 id="空港wifi">空港WiFi</h4>

<p><img src="/assets/aacd5f5cacd1/1*evDWJrEApdI2laaMO01asw.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*evDWJrEApdI2laaMO01asw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YqPFrPIOePpu3WgHmBMXBA.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YqPFrPIOePpu3WgHmBMXBA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*7sCEBxL7NtIZHBeap-IW-w.webp" alt="" loading="lazy" decoding="async" width="560" height="1127" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjAiIGhlaWdodD0iMTEyNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*7sCEBxL7NtIZHBeap-IW-w.png" /></p>

<blockquote>
  <p><em>岡山空港の無料WiFiは接続後にメールアドレスを入力し、届いたメールのリンクをクリックして有効化しないと継続して使えません。Visit Japanのためだけなら、接続してから10分以内にウェブページを開き、入国用QRコードを表示すれば利用可能です。</em></p>
</blockquote>

<h4 id="-1704-岡山空港からjr岡山駅行きのバスに乗車">~= 17:04 岡山空港からJR岡山駅行きのバスに乗車</h4>

<p><img src="/assets/aacd5f5cacd1/1*YNxPMPmNH-YBWNemZR6t-Q.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YNxPMPmNH-YBWNemZR6t-Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*4c4diTl_B42J1RTeChslgA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4c4diTl_B42J1RTeChslgA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*k3bf2CWOwFKCWeC1eC1yTQ.webp" alt="最新の時刻表は公式サイトをご参照ください" loading="lazy" decoding="async" width="371" height="634" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNzEiIGhlaWdodD0iNjM0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*k3bf2CWOwFKCWeC1eC1yTQ.png" /></p>

<p><a href="https://www.okayama-airport.org/tw/access/bus" target="_blank">最新の時刻表は公式サイトをご参照ください</a></p>

<ul>
  <li>
    <p>空港はとても小さく、道に沿って進むと岡山駅行きのバス乗り場に出ます。スタッフが案内してくれるので、迷うことなくそのまま乗れます。</p>
  </li>
  <li>
    <p><strong>便数が少ないため、バスは定時運行のほか、飛行機の到着時間に合わせて臨時便も運行されます。満席で乗れない心配はなく、満席の場合は追加便が出ます。</strong><br />
（<a href="https://www.okayama-airport.org/tw/access/bus" target="_blank">定時運行では19:05までバスがありません</a> が、実際には臨時便があります。）</p>
  </li>
  <li>
    <p><a href="https://www.ptt.cc/bbs/Japan_Travel/M.1730096575.A.AB6.html" target="_blank">2024/11/30までにパスポートを提示すると</a> 無料で乗車可能；無料シャトルバスは不定期運行で、<a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/">昨年来た時はありませんでした</a>。</p>
  </li>
</ul>

<h4 id="-1800-jr岡山駅に到着">~= 18:00 JR岡山駅に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*8OhJp66_cz7XpEzC8I6WpQ.webp" alt="" loading="lazy" decoding="async" width="912" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*8OhJp66_cz7XpEzC8I6WpQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*nxBsum1hduuDJJluFTz4DQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1010" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*nxBsum1hduuDJJluFTz4DQ.png" /></p>

<p>帰宅ラッシュで少し渋滞し、18:00頃に岡山駅に到着しました。<strong>（予定より30分遅れ）</strong></p>

<h4 id="jr岡山駅でjrパスを受け取り翌日の松江行きの切符を予約する">JR岡山駅でJRパスを受け取り、翌日の松江行きの切符を予約する</h4>

<p><img src="/assets/aacd5f5cacd1/1*-2saCSONEdJw9FIYeVFZ4Q.webp" alt="" loading="lazy" decoding="async" width="953" height="1192" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTMiIGhlaWdodD0iMTE5MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*-2saCSONEdJw9FIYeVFZ4Q.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*KJeCftSlvW2t-a1Ef5JvEA.webp" alt="" loading="lazy" decoding="async" width="952" height="1232" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTIiIGhlaWdodD0iMTIzMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*KJeCftSlvW2t-a1Ef5JvEA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*t9I2iSC2-97Dv5fX6FNqWw.webp" alt="" loading="lazy" decoding="async" width="640" height="745" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NDAiIGhlaWdodD0iNzQ1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*t9I2iSC2-97Dv5fX6FNqWw.png" /></p>

<ul>
  <li>
    <p>公式サイトで<a href="https://www.westjr.co.jp/global/tc/ticket/receive/?railpass=11&amp;mco=1&amp;area=0" target="_blank">JRパス引換可能な駅</a>を確認できます。すべての駅で引き換えできるわけではありません！
（JR岡山駅は可能です）</p>
  </li>
  <li>
    <p>岡山駅で自動券売機を探し、中央の緑色の機械に並びました。この機械だけがJRパスの交換に対応しています。</p>
  </li>
</ul>

<p><strong>交換手続き：</strong></p>

<p><strong>パスポートと購入したJR PassのQRコードを準備し、右上の言語で「繁体字中国語」を選択後、左下の黄色い「QRコードの読取り」ボタンを直接タップして引き換えができます。</strong></p>

<blockquote>
  <p><strong><em>利用開始日を選択できます</em></strong> <em>、指定席の予約可能時間も利用開始日から計算されます。<strong>⚠️</strong></em></p>
</blockquote>

<blockquote>
  <p><em>(私は明日から始めることにしました)</em></p>
</blockquote>

<p>JRパスのQRコードとパスポートを順番にスキャンするだけで、交換が完了します。</p>

<p><img src="/assets/aacd5f5cacd1/1*nj6t65muUKTM8rL9b9MnUQ.webp" alt="JRパスのQRコード" loading="lazy" decoding="async" width="845" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NDUiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*nj6t65muUKTM8rL9b9MnUQ.png" /></p>

<p>JRパス QRコード</p>

<p><strong>交換結果：</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*A-kqDIwfmGwif12qTiUU1g.webp" alt="上図は昨年交換したJRパスの例です" loading="lazy" decoding="async" width="604" height="770" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDQiIGhlaWdodD0iNzcwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*A-kqDIwfmGwif12qTiUU1g.png" /></p>

<p>上の写真は昨年交換したJRパスを例として使用しています。</p>

<p>交換後、3枚の券がもらえます。長方形の2枚は説明書で、使用しません；<strong>PASSと印刷されたこの券が最も重要で、駅での乗車や改札通過はこの券で行うので、大切に保管してください！</strong></p>

<h4 id="jr指定席の予約">JR指定席の予約</h4>

<p>ここは非常に重要です。 <a href="https://www.westjr.co.jp/global/tc/ticket/pass/kansai_sanin/" target="_blank">JR Pass 関西＆山陰周遊券公式サイト</a> によると、<a href="https://www.westjr.co.jp/global/tc/ticket/pass/pdf/Reserved_seats_tc.pdf" target="_blank"><strong>山陰地区へ向かうJRやくも号は全席指定席</strong></a> <strong>であり、自由席はありません⚠️⚠️⚠️（2024年3月16日開始）</strong>。必ず事前に座席指定が必要です。</p>

<blockquote>
  <p><em>ネットで事前予約も可能だと思います。<a href="https://medium.com/ztravel/%E9%81%8A%E8%A8%98-2024-%E4%BA%8C%E8%A8%AA%E4%B9%9D%E5%B7%9E-9-%E6%97%A5%E8%87%AA%E7%94%B1%E8%A1%8C-%E7%B6%93%E9%87%9C%E5%B1%B1-%E5%8D%9A%E5%A4%9A%E9%83%B5%E8%BC%AA%E5%85%A5%E5%A2%83-cb65fd5ab770?source=collection_home---4------1-----------------------" target="_blank">以前は博多から由布院までのJRをネットで予約しました</a>。ただし、確認が必要です。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*jPSXmntXpBrCzRGnB0Ty5A.webp" alt="" loading="lazy" decoding="async" width="1200" height="1051" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwNTEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*jPSXmntXpBrCzRGnB0Ty5A.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YUzrKBjkuis18Az9sZMM5Q.webp" alt="" loading="lazy" decoding="async" width="751" height="575" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NTEiIGhlaWdodD0iNTc1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*YUzrKBjkuis18Az9sZMM5Q.png" /></p>

<blockquote>
  <p><em>Googleマップの交通情報は不完全で、詳細な時刻や<strong>列車名</strong>は<a href="https://www.westjr.co.jp/global/sc/timetable/" target="_blank">JR公式サイト</a>で確認できます。<strong>⚠️⚠️⚠️</strong></em></p>
</blockquote>

<p><strong>JR Pass 指定席予約の流れ：</strong></p>

<ul>
  <li>
    <p><a href="https://www.westjr.co.jp/global/tc/ticket/pass/kansai_sanin/" target="_blank"><strong>JRパス 関西＆山陰周遊券</strong></a> <strong>は機械で6回まで指定席の予約が可能で、それ以上は窓口での予約が必要です。地域によってJRパスの回数や制限が異なるため、公式サイトでご確認ください。</strong></p>
  </li>
  <li>
    <p>出発地と目的地の<strong>JR駅の英語名</strong>を事前に調べておく<br />
例：OKAYAMA（岡山） -&gt; MATSUE（松江）</p>
  </li>
  <li>
    <p>JR駅の英語名に注意してください。<em>例えば<a href="/posts/z-度旅行遊記/九州自由行-福岡-長崎-熊本を巡る10日間の独り旅ガイド-d78e0b15a08a/">福岡に行くならHakataを入力</a></em> XD</p>
  </li>
  <li>
    <p>最初に「繁体字中国語」を選択してください。</p>
  </li>
  <li>
    <p>第二歩で「JR Passの乗車券」を直接挿入します。<br />
（複数人で一緒に座席指定をする場合は、第四歩で続けて挿入してください。）</p>
  </li>
  <li>
    <p>その他の手順は以下の動画を参考に予約を完了してください：</p>
  </li>
</ul>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/oG8xrxEC6mk" title="JR Pass 預約指定席示範" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<blockquote>
  <p><em>動画は安来駅（Yasugi）から鳥取駅（Tottori）への予約手順の一例として撮影したものです。</em></p>
</blockquote>

<blockquote>
  <p><em>(あの駅では自動券売機に誰も並んでいなかったため、スマホで全過程を撮影できました)</em></p>
</blockquote>

<p><strong>予約完了：</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*wdAemMFceaXQ6mZEPJfzWQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*wdAemMFceaXQ6mZEPJfzWQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*9E0CaLNkFZHyp6RfFbW8VQ.webp" alt="" loading="lazy" decoding="async" width="938" height="1226" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzgiIGhlaWdodD0iMTIyNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*9E0CaLNkFZHyp6RfFbW8VQ.png" /></p>

<ul>
  <li>
    <p>便の時間と翌日の予定の都合で、早朝7:05の便を予約し、先に松江のホテルに荷物を預けに行きます。</p>
  </li>
  <li>
    <p><strong>実際の乗降はJRパス（上の写真のもの）を使用します</strong> ⚠️⚠️⚠️、指定券は車両と座席番号を確認するためのものです。</p>
  </li>
  <li>
    <p>窓側の席はもうなく、通路側しか座れませんでした QQ</p>
  </li>
</ul>

<p><img src="/assets/aacd5f5cacd1/1*eWbl5HfHDsgs10xMbQByBA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*eWbl5HfHDsgs10xMbQByBA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*flqVSVO61pO1j1rk6sYICw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*flqVSVO61pO1j1rk6sYICw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*cFmuaiXspF7Fk3FeKY_Vwg.webp" alt="" loading="lazy" decoding="async" width="952" height="1225" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTIiIGhlaWdodD0iMTIyNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*cFmuaiXspF7Fk3FeKY_Vwg.png" /></p>

<p>岡山駅で適当にビーフカツ弁当を買い、コンビニで飲み物や食べ物を購入してからホテルで休みました。岡山駅は現在改装中で、最終日の帰路にまた岡山に戻ります。</p>

<p><img src="/assets/aacd5f5cacd1/1*5OK4O6vRpvTbBHY1or45Ww.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*5OK4O6vRpvTbBHY1or45Ww.jpeg" /></p>

<p>桃太郎商店街から歩いて5分でホテルに着きます。</p>

<h4 id="-1900-ホテルに戻って食事と休憩">~= 19:00 ホテルに戻って食事と休憩</h4>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/UfWKBa1FAto" title="東橫INN 岡山站東口" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p><img src="/assets/aacd5f5cacd1/1*1JJAxuSJ6NLnq4lRXZPajw.webp" alt="" loading="lazy" decoding="async" width="1200" height="843" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1JJAxuSJ6NLnq4lRXZPajw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*5aXGicaDQzX-9EREx0ooaw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*5aXGicaDQzX-9EREx0ooaw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*0XBFIrZROFSOuAr7psn7NA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*0XBFIrZROFSOuAr7psn7NA.jpeg" /></p>

<p>お弁当の量は少し少なめで、岡山の白桃の缶チューハイがとても美味しい！懐かしい日本のコンビニ（ファミリーマート）のホットドッグと唐揚げも加えて、今夜は大満足。おやすみ、岡山！明日の早起きに備えてしっかり準備します。</p>

<h4 id="岡山後楽園ライトアップ"><a href="http://genso-teien.okayama.jp/" target="_blank">岡山後楽園ライトアップ</a></h4>

<p>2024年の岡山後楽園のライトアップは11月15日（金）から11月24日（日）までで、訪れた日はまだ点灯していませんでした。もしライトアップがあれば、ぜひ見に行ってください、とても綺麗です。</p>

<p><img src="/assets/aacd5f5cacd1/1*tVwuOQS4DytQGzfk3tn52g.webp" alt="去年 2023年 山陽ライトアップで撮影した写真" loading="lazy" decoding="async" width="1242" height="939" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjQyIiBoZWlnaHQ9IjkzOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*tVwuOQS4DytQGzfk3tn52g.png" /></p>

<p><a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/">昨年2023年山陽灯りの写真</a></p>

<h3 id="day-2-1113-水曜日-島根--出雲大社宍道湖の夕日">Day 2 (11/13 水曜日) 島根 — 出雲大社、宍道湖の夕日</h3>

<h4 id="0705-やくも1号に乗って松江へ向かう">07:05 やくも1号に乗って松江へ向かう</h4>

<p><img src="/assets/aacd5f5cacd1/1*-ppEnPrSVSls2IfkppB_pA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*-ppEnPrSVSls2IfkppB_pA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*NBhG889zmADfQDGI-7zlAQ.webp" alt="" loading="lazy" decoding="async" width="963" height="751" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjMiIGhlaWdodD0iNzUxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*NBhG889zmADfQDGI-7zlAQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*yb0D7yt38ygSmnGJyEjoEA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*yb0D7yt38ygSmnGJyEjoEA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*168t2gezMC-ucwNzG3_m5g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*168t2gezMC-ucwNzG3_m5g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*0DUCHWLSu7X5LG35oylmBw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*0DUCHWLSu7X5LG35oylmBw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*m4JyAVEfNrUoaIt1Hk3Zeg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*m4JyAVEfNrUoaIt1Hk3Zeg.jpeg" /></p>

<p>車内はかなり快適で、前後に荷物置き場があり、直接荷物を置けます。座席には充電ポートもあります。</p>

<p><img src="/assets/aacd5f5cacd1/1*vg7v1Xz5RlcQ9KqnMwiZjw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*vg7v1Xz5RlcQ9KqnMwiZjw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*M8ciQoiAy5GWHQoa34vo1w.webp" alt="" loading="lazy" decoding="async" width="879" height="994" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzkiIGhlaWdodD0iOTk0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*M8ciQoiAy5GWHQoa34vo1w.png" /></p>

<p>総所要時間は約2時間45分で、山を越え谷を抜ける感覚が味わえます。早朝は多くの地域でまだ霧がかかっており、まるでトンネルを抜けて桃源郷に来たような雰囲気でした。残念ながら窓側の席が取れず、遠くから景色を見るだけでした。</p>

<h4 id="0949-松江に到着">09:49 松江に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*RNcfgkoIlBNqAbZiJGXUeA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*RNcfgkoIlBNqAbZiJGXUeA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*wuK_7kxYguDnQoYd5nNXtA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*wuK_7kxYguDnQoYd5nNXtA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*GfeSKNvv30aqgIOUIcVAzw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*GfeSKNvv30aqgIOUIcVAzw.jpeg" /></p>

<p>松江の天気はとても良かった☀️。松江駅に到着後、すぐに今夜宿泊するホテル「<a href="https://www.station.matsue-urban.co.jp/en/" target="_blank"><strong>Matsue Urban Hotel</strong></a>」へ行き、荷物を預けました。</p>

<p><img src="/assets/aacd5f5cacd1/1*YCar9o50KKuyrx5blLVipg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YCar9o50KKuyrx5blLVipg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*58UjwwimiMZZS5fhCc2o7w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*58UjwwimiMZZS5fhCc2o7w.jpeg" /></p>

<p>荷物を預けて松江駅に戻ったのはおよそ10:00で、再度指定席を取り、10:48発のやくも3号で松江から出雲市へ向かいます。</p>

<blockquote>
  <p><strong><em>昨日、岡山から松江への座席指定をした際に、松江から出雲市への分も一緒に指定しておくべきでした。</em></strong> <em>午後に夕日を見に行きたかったので、先に松江で荷物を預けましたが、そうでなければ出雲市まで直接行って、中途で乗り換えの時間を無駄にしなかったのに。</em></p>
</blockquote>

<blockquote>
  <p><em>また、一畑電車大社線を利用して出雲大社へ行くこともできます。所要時間はほぼ同じです。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*Wvd6qczYLcEb8XywbGV_Vg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Wvd6qczYLcEb8XywbGV_Vg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*602_X70DAMAYJiEI2d024Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*602_X70DAMAYJiEI2d024Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Ji2S8d1orIkJB5Wyu3DCSw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Ji2S8d1orIkJB5Wyu3DCSw.jpeg" /></p>

<p>まだ少し時間があったので、コンビニに行っておにぎり2つ、コーヒー、唐揚げを買い、昼食にしました。</p>

<p><img src="/assets/aacd5f5cacd1/1*OkaENzl4tJ0nSMqMSznEmw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OkaENzl4tJ0nSMqMSznEmw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*NNFURE5UfVdWOgkpYuAtrg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*NNFURE5UfVdWOgkpYuAtrg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*5-vTR2_TeMIlIiPggNON5w.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*5-vTR2_TeMIlIiPggNON5w.jpeg" /></p>

<p>道中、宍道湖を通ります。とても大きくて最初は海かと思いましたが、実は湖です。</p>

<blockquote>
  <p><em>席指定はDの窓側を選べば宍道湖が直接見えますが、私はA側を選んだため山側で見えませんでした QQ。</em></p>
</blockquote>

<h4 id="11月12日-出雲市到着">11月12日 出雲市到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*IGzRRA0zChR7eosgVBM30g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*IGzRRA0zChR7eosgVBM30g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*_dWPzssuOTsPLhGlPeaxBg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_dWPzssuOTsPLhGlPeaxBg.jpeg" /></p>

<p>松江駅に到着後、急いで走りながら11:25発の一畑電車北松江線に乗り、まず川跡駅へ向かいました。</p>

<blockquote>
  <p><em>一畑電車は交通系ICカードが使えないため、改札口の自動券売機（電子決済対応）で先に切符を購入してください。購入方法がわからない場合は、駅員に「Izumo Taisha」（出雲大社）までと言えば問題ありません。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*zOWAvtPBUa4Q6p_O0UI_4A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*zOWAvtPBUa4Q6p_O0UI_4A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*hqp8E0znWzflcoF_wdXbYA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*hqp8E0znWzflcoF_wdXbYA.jpeg" /></p>

<p>川跡駅で乗り換えが必要です（皆と一緒に向かいのホームへ移動してください）、一畑電車大社線に乗り換えて出雲大社前駅へ向かいます。</p>

<h4 id="約12時に出雲大社に到着">約12時に出雲大社に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*DbbHj7dvLzIZ5yucQPqW2Q.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*DbbHj7dvLzIZ5yucQPqW2Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*TNniVRe3T0Lx2h8ZEO6UoQ.webp" alt="" loading="lazy" decoding="async" width="902" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*TNniVRe3T0Lx2h8ZEO6UoQ.png" /></p>

<p>大神前の表参道はとても静かで美しく、時間があればここにもたくさんの小さな店や美味しいものがあります。</p>

<blockquote>
  <p><em>後で知ったのですが、出雲の四つの鳥居も有名で、そのうちの一つである白い大鳥居は、出雲駅の表参道から神社と反対方向に歩くと入口で見つけることができます：</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*PsT0vPHhgZXJUJVbJzg9TA.webp" alt="出典：島根観光公式サイト" loading="lazy" decoding="async" width="1268" height="823" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjY4IiBoZWlnaHQ9IjgyMyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*PsT0vPHhgZXJUJVbJzg9TA.png" /></p>

<p><a href="https://www.kankou-shimane.com/zh-tw/highlights/1615" target="_blank">出典：島根観光公式サイト</a></p>

<blockquote>
  <p><em>詳細は <a href="https://www.kankou-shimane.com/zh-tw/highlights/1615" target="_blank">島根観光公式サイト</a> をご覧ください</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*l9SL74ldAxYcnEpLmIFgsA.webp" alt="" loading="lazy" decoding="async" width="1200" height="875" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg3NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*l9SL74ldAxYcnEpLmIFgsA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*NmTX-LAuUYpyNxZH1iyOmA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*NmTX-LAuUYpyNxZH1iyOmA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*lL6Lshf934FqRMAHwuf8Sw.webp" alt="" loading="lazy" decoding="async" width="988" height="1029" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5ODgiIGhlaWdodD0iMTAyOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*lL6Lshf934FqRMAHwuf8Sw.png" /></p>

<p>出雲大社の入口まで上ると、訪れた日時が <code class="language-plaintext highlighter-rouge">2024/11/13</code> でちょうど <strong>神在祭</strong> の期間中（<code class="language-plaintext highlighter-rouge">2024 令和6年 11/11～11/17</code>）だったため、参拝に訪れる日本人が非常に多かったです。</p>

<blockquote>
  <p><em>日本では毎年旧暦の10月（西暦11月）、全国の八百万の神々が出雲に集まり「神議」を行い、人間の縁結びや自然の調和について話し合います。</em></p>
</blockquote>

<blockquote>
  <p><em>したがって、<strong>この月は日本の他の地域では「神無月」（神がいない月）と呼ばれ、ほとんど祭りがありません</strong>。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>出雲だけで「神在月」と呼ばれ、出雲地域にだけ神様がいることを意味します。</em></strong></p>
</blockquote>

<blockquote>
  <p><em>祭りには神を迎える「神迎祭」、良縁を祈る「縁結大祭」、そして神を送り出す「神送り祭」が含まれます</em></p>
</blockquote>

<blockquote>
  <p><strong><em>出雲大社の主神：大国主命（おおくにぬしのみこと）</em></strong></p>
</blockquote>

<p>本当に偶然ですが、当初スケジュールを組んだときは特にこの時期を選んだわけではなく、観光情報を調べているうちに知りました。</p>

<p><img src="/assets/aacd5f5cacd1/1*mHn3NX4zb31WmXFITQBOIQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*mHn3NX4zb31WmXFITQBOIQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*iehGyLgSPf4LgUzjhMjfzw.webp" alt="" loading="lazy" decoding="async" width="952" height="1285" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTIiIGhlaWdodD0iMTI4NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*iehGyLgSPf4LgUzjhMjfzw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*IVJtJR2htbOjimqgqKvLrg.webp" alt="" loading="lazy" decoding="async" width="896" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4OTYiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*IVJtJR2htbOjimqgqKvLrg.png" /></p>

<p>鳥居の入口をくぐってから神社までさらに約5分歩きます。</p>

<h4 id="日本一大きな日の丸国旗">日本一大きな「日の丸」国旗</h4>

<p><img src="/assets/aacd5f5cacd1/1*WBerwVlV_I8PeYqj2KRX1w.webp" alt="" loading="lazy" decoding="async" width="959" height="1183" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTkiIGhlaWdodD0iMTE4MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*WBerwVlV_I8PeYqj2KRX1w.png" /></p>

<p>神社に入って左を見ると、高くそびえる旗竿があり、その上には日本最大の日の丸の国旗（約75畳、137平方メートル）が掲げられています。</p>

<p>この旗竿の方向に進むと「神楽殿」に着きます。ここには日本一の大きさの<a href="https://sanin-japan.com/zh-tw/special/territory-of-the-gods-yokozuna-and-izumo-taisha/" target="_blank">注連縄</a>があります。</p>

<p><img src="/assets/aacd5f5cacd1/1*x8zuQYtIXNILxGLkMjQbJg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1056" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*x8zuQYtIXNILxGLkMjQbJg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*3WjUHQV3lwqRTi3IegRb6w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*3WjUHQV3lwqRTi3IegRb6w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*KeY6bAoW8DsPQf4BtMuhcA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*KeY6bAoW8DsPQf4BtMuhcA.jpeg" /></p>

<p>間近で見ると本当に大きく、特に他の神社の一般的なしめ縄と比べると、約10倍の大きさです。（長さは14メートル、重さは5トンで、数年ごとに交換され、すべて手作りです）</p>

<blockquote>
  <p><em>「神楽殿」が一番大きいので、最初に本殿だと勘違いしないでください。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*KZnzwRAX5CdPvprYWwCzTg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*KZnzwRAX5CdPvprYWwCzTg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*L3BUl_V1wCtc9hiRiiGlqw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*L3BUl_V1wCtc9hiRiiGlqw.jpeg" /></p>

<p>一周回ってみると、人がかなり多く、長い列に並んで参拝する場所もありました。</p>

<p><img src="/assets/aacd5f5cacd1/1*7iUkAuzNjt8d1wHbtiUWhQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*7iUkAuzNjt8d1wHbtiUWhQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*_DCfvI3CSAqMeC0hnZzCHA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_DCfvI3CSAqMeC0hnZzCHA.jpeg" /></p>

<blockquote>
  <p><em>出雲大社の参拝方法は他の神社と異なります：⚠️⚠️⚠️</em></p>
</blockquote>

<blockquote>
  <p><em>これは<a href="https://www.japan.travel/hk/spot/937/" target="_blank"><strong>最初に二礼し、四拍手して、最後にもう一度お辞儀をする</strong></a>ことです。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*uKMCGxlcrtLXp_wuz0Okqg.webp" alt="" loading="lazy" decoding="async" width="890" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4OTAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*uKMCGxlcrtLXp_wuz0Okqg.png" /></p>

<p>神在祭期間限定のお守りを購入しました。 <strong>(この一週間のみ販売)</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*Zg626XNieV5uT7JLszzsXQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Zg626XNieV5uT7JLszzsXQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*kGHi22HqIHPB3-vtdGXShg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*kGHi22HqIHPB3-vtdGXShg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*KUh8eckUM7jasbTZFl3nmw.webp" alt="" loading="lazy" decoding="async" width="815" height="1019" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MTUiIGhlaWdodD0iMTAxOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*KUh8eckUM7jasbTZFl3nmw.png" /></p>

<p>参拝後に御朱印帳をいただき、出雲大社の記念印を押しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*M2zO2XrTYc941f8q6n439A.webp" alt="出雲神在月神在社巡拝五つの神社の位置。" loading="lazy" decoding="async" width="1400" height="664" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjY2NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*M2zO2XrTYc941f8q6n439A.png" /></p>

<p><a href="https://www.google.com/maps/d/u/0/edit?mid=1InF3hfsLjC7uW8T2J2ojcXJ_Ej3Eo0k&amp;usp=sharing" target="_blank">出雲神在月神在社巡り五大神社の位置。</a></p>

<p>時間が限られていたため、出雲の他の神社には参拝できませんでした。レンタカーがないと集めるのは難しいと感じました。</p>

<h4 id="-1245-徒歩で-稲佐の浜-稲佐海岸へ">~= 12:45 徒歩で 稲佐の浜 稲佐海岸へ</h4>

<p><img src="/assets/aacd5f5cacd1/1*tp8izFV2pcWAkHrOxguusw.webp" alt="" loading="lazy" decoding="async" width="960" height="235" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjAiIGhlaWdodD0iMjM1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*tp8izFV2pcWAkHrOxguusw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*-hHa8tNAXHA8hkuI3ySAVA.webp" alt="" loading="lazy" decoding="async" width="953" height="1245" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTMiIGhlaWdodD0iMTI0NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*-hHa8tNAXHA8hkuI3ySAVA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Yj37xFyP1gByfLvNdDTOtA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*Yj37xFyP1gByfLvNdDTOtA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*RQmCSnIsPBVcJW1r9nSS3w.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*RQmCSnIsPBVcJW1r9nSS3w.jpeg" /></p>

<p>バスの本数が少ないため、徒歩で行くしかなく、約15分かかります。途中で出雲阿国の墓を通り過ぎ、道なりに進むと稲佐の浜に着きます。</p>

<blockquote>
  <p><strong><em>稲佐の浜：</em></strong></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*YRUdkflWxYERcA62-AQ2Eg.webp" alt="出典：島根観光公式サイト" loading="lazy" decoding="async" width="1200" height="1015" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjEwMTUiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*YRUdkflWxYERcA62-AQ2Eg.png" /></p>

<p><a href="https://www.kankou-shimane.com/zh-tw/destinations/991" target="_blank">出典：島根観光公式サイト</a></p>

<blockquote>
  <p><em>日本神話に深く由来するスポットで、写真の小島は弁天島と呼ばれ、島には小さな祠があります。</em></p>
</blockquote>

<blockquote>
  <p><a href="https://www.kankou-shimane.com/zh-tw/destinations/991" target="_blank"><em>日本百選の海岸で、「夕日の聖地出雲」のランドマークである弁天島の背後に夕陽が海に沈む景色はとても美しく、日本遺産にも登録されています。ここは神迎えの儀式が行われ、日本全国の神々を迎え入れる場所です。</em></a></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*PIyVVCAMngDrgpErhjGRMw.webp" alt="" loading="lazy" decoding="async" width="958" height="1245" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NTgiIGhlaWdodD0iMTI0NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*PIyVVCAMngDrgpErhjGRMw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*lYRW_DUWWfI1aDJVkBtphA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*lYRW_DUWWfI1aDJVkBtphA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*tI4HMhJCNhlYlHKkFIJm9w.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*tI4HMhJCNhlYlHKkFIJm9w.jpeg" /></p>

<p>訪問時間が限られていたため、夕日を見ることができず、少し散策してから戻りました。</p>

<blockquote>
  <p><strong><em>台湾に戻ってからInstagramを見て、ここで<a href="https://www.japaholic.com/tw/article/detail/887878-%E4%BE%86%E5%B3%B6%E6%A0%B9%E7%B8%A3%E5%87%BA%E9%9B%B2%E5%A4%A7%E7%A4%BE%E6%B1%82%E5%BA%87%E8%AD%B7%E8%A6%81%E6%8C%96%E7%A0%82%EF%BC%9F%E7%A8%BB%E4%BD%90%E4%B9%8B%E6%BF%B1%E5%8F%96%E7%A5%9E%E7%A0%82%E6%B1%82%E5%BE%A1%E5%AE%88%E6%95%99%E5%AD%B8" target="_blank">砂御守が授与されている</a>と知りました：</em></strong></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*9XZ8oaxmYdrNU3I68EgTnw.webp" alt="https://www.instagram.com/reel/CynStXPyZAX/" loading="lazy" decoding="async" width="696" height="620" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2OTYiIGhlaWdodD0iNjIwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*9XZ8oaxmYdrNU3I68EgTnw.png" /></p>

<p><a href="https://www.instagram.com/reel/CynStXPyZAX/?utm_source=ig_web_copy_link" target="_blank">https://www.instagram.com/reel/CynStXPyZAX/</a></p>

<p>出雲大社のバス停まで歩いて戻り、JR出雲駅行きのバスに乗ります。</p>

<p><img src="/assets/aacd5f5cacd1/1*AqsQ2S3q61tJaq7k6fgdIA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*AqsQ2S3q61tJaq7k6fgdIA.jpeg" /></p>

<p>出雲大社の参拝を待つ車が駐車場まで途切れなく続いているのが見えます。</p>

<p><img src="/assets/aacd5f5cacd1/1*kL0wZHJiMcqSCE3ChzTpNQ.webp" alt="" loading="lazy" decoding="async" width="759" height="415" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NTkiIGhlaWdodD0iNDE1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*kL0wZHJiMcqSCE3ChzTpNQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*8aaLagUno9PZTAYUCpX4-Q.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*8aaLagUno9PZTAYUCpX4-Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*XrDT2aXpUPfF7NT5IEFFNA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*XrDT2aXpUPfF7NT5IEFFNA.jpeg" /></p>

<p>出雲大社のバス停はお土産屋さんを通り抜けてトイレの裏側にあります。小さくて最初は間違えて待つのをとても心配しました。</p>

<p><strong>この時刻は約13:15で、13:40発のJR出雲駅行きのバスを待つ必要があり、お腹が空いていたので先に前の土産物店と隣の店で何か買って手軽に食べました。</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*FYPk9dJKH166TgfMJbKinA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*FYPk9dJKH166TgfMJbKinA.jpeg" /></p>

<p>お土産店でいくつか中二ステッカーを買いました。</p>

<h4 id="1340-バスに乗ってjr出雲駅へ戻る"><strong>13:40 バスに乗ってJR出雲駅へ戻る</strong></h4>

<p><img src="/assets/aacd5f5cacd1/1*gvzJ1xXYnLyxNU_HAlFyNA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*gvzJ1xXYnLyxNU_HAlFyNA.jpeg" /></p>

<blockquote>
  <p><em>出雲に戻る途中で、日本人の方がモバイルバッテリーを借りに来ました。彼のスマホは完全に電源が切れていて、ちょうど確認のために（ついでに覚えている少ない日本語の練習も兼ねて）「<strong>このバスはJR出雲市駅へ行きますか</strong>」と聞くと、彼は「<strong>はい</strong>」と答えました。（私も「はい」しか聞き取れませんでした）。</em></p>
</blockquote>

<h4 id="-1415-jr出雲市駅に戻る">~= 14:15 JR出雲市駅に戻る</h4>

<p>(日没前に宍道湖の夕日を見に行く。情報によると<strong>当日17:05に太陽が沈む</strong>)</p>

<p><img src="/assets/aacd5f5cacd1/1*roLGAz0BE_7yrZ7010cJ1w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*roLGAz0BE_7yrZ7010cJ1w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*JxPpTZphqlQpjXjOlEmRfA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*JxPpTZphqlQpjXjOlEmRfA.jpeg" /></p>

<p>今回は八雲号に乗らず、14:54発の米子行き普通列車に乗りました。Google Mapの案内に従い、乃木駅で降りて宍道湖夕日展望スポットまで歩きました。</p>

<p><img src="/assets/aacd5f5cacd1/1*6-c6bp49Is4qZ_IdbiMPCg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*6-c6bp49Is4qZ_IdbiMPCg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*kXIIylCmu_fP_FA6IGQ3_g.webp" alt="" loading="lazy" decoding="async" width="947" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDciIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*kXIIylCmu_fP_FA6IGQ3_g.png" /></p>

<blockquote>
  <p><em>松江方面に行く場合、左側の席（A）に座ると宍道湖を通過する際に湖の景色が直接見えます。そう、また席を間違えて山側に座ってしまいました。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>この駅の普通列車はボタンを押さないとドアが開かない、初めての経験。</em></strong> <em>⚠️</em></p>
</blockquote>

<h4 id="1535-乃木駅に到着">~=15:35 乃木駅に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*4CNzZ0RmgGHRVr4NJ899zA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*4CNzZ0RmgGHRVr4NJ899zA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*5mXpmq_hk-UlrD_KF-x1xg.webp" alt="" loading="lazy" decoding="async" width="489" height="583" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0ODkiIGhlaWdodD0iNTgzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*5mXpmq_hk-UlrD_KF-x1xg.png" /></p>

<p>乃木駅はとても小さく、駅員も改札機もありません。<strong>JRパスを持っている場合は、そのまま改札を通らずに出場してください。JRパスを回収箱に入れないように注意してください。⚠️⚠️⚠️</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*hiBPok9dbi9XGQeAPRQ5NQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*hiBPok9dbi9XGQeAPRQ5NQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*E4Yd7PB_MJh1CyuwFJS3zw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*E4Yd7PB_MJh1CyuwFJS3zw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*MAtnP-62r3MY0NSPPSy0yg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*MAtnP-62r3MY0NSPPSy0yg.jpeg" /></p>

<p>乃木駅から歩くのは少し失敗でした。ここはとても寂しくて人がほとんどいません…</p>

<p>でも途中で7–11があって、ホットドッグと唐揚げ、飲み物を買って、夕日を見ながら食べました。</p>

<h4 id="1600-宍道湖の夕日を見る">16:00 宍道湖の夕日を見る</h4>

<p><img src="/assets/aacd5f5cacd1/1*ptNqLKfhX0azm3b5HxfBZg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*ptNqLKfhX0azm3b5HxfBZg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*krl-46lxVoh33r7TcwgpkQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*krl-46lxVoh33r7TcwgpkQ.jpeg" /></p>

<blockquote>
  <p><a href="https://www.kankou-shimane.com/zh-tw/destinations/985" target="_blank"><em>宍道湖は日本で7番目に大きい湖で、宍道湖の夕日は日本一の夕日と称されます。</em></a></p>
</blockquote>

<blockquote>
  <p><em>写真の中の小島、嫁島神社には白い小さな鳥居があります。</em></p>
</blockquote>

<blockquote>
  <p><em>以前に間違えて宍道湖を穴道湖と書いてしまいました。</em></p>
</blockquote>

<p>一羽のサギがいます。</p>

<p><img src="/assets/aacd5f5cacd1/1*ceThDvVZuO8MOR9OXn74ew.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ceThDvVZuO8MOR9OXn74ew.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*tz5i0B2jBta5vBsz-JMWHQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*tz5i0B2jBta5vBsz-JMWHQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*1oDwRChVUUz-EVOv-HAWkw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1oDwRChVUUz-EVOv-HAWkw.jpeg" /></p>

<p>上に行くと島根県立美術館があります。そちらは賑やかでカフェもありますが、階段の広場からの景色の角度の方が良いです。</p>

<h4 id="1645-夕陽が沈む">16:45 夕陽が沈む</h4>

<p><img src="/assets/aacd5f5cacd1/1*rmwJe1rnyjhQkJ9erx7q_w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*rmwJe1rnyjhQkJ9erx7q_w.jpeg" /></p>

<p>最初はあまり感じませんでしたが、夕日に近づくにつれて初めての夕日の魅力を実感しました。さっきのサギも景色にうまく溶け込んでいました。</p>

<p><img src="/assets/aacd5f5cacd1/1*CdDLOmzP80ovaY94HDD3Wg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*CdDLOmzP80ovaY94HDD3Wg.jpeg" /></p>

<p>夕日が地平線に近づくと、肉眼で見える速さで時間が過ぎていきます。太陽は一分一秒ごとに沈んでいきます。</p>

<p><img src="/assets/aacd5f5cacd1/1*pT7mh8XcC_Xt1_BO61SbfQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*pT7mh8XcC_Xt1_BO61SbfQ.jpeg" /></p>

<p>あっという間に17:01にはもう太陽が見えなくなりました。</p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/K-xDmVjqG9g" title="20241113 宍道湖夕日" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<blockquote>
  <p><strong><em>本当に美しくて、癒されます。</em></strong></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*OG9M3KjHgChA0KY-MyBQPA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OG9M3KjHgChA0KY-MyBQPA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*fzAcAYv8VNf8TjnrqwuqSg.webp" alt="" loading="lazy" decoding="async" width="923" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*fzAcAYv8VNf8TjnrqwuqSg.png" /></p>

<p>最後にもう一度<a href="https://maps.app.goo.gl/LRQAMZNht9km1DFm6" target="_blank">夕日観賞階段プラットフォーム</a>を見渡し、夕日を眺める人々を一緒に眺めました。</p>

<p><img src="/assets/aacd5f5cacd1/1*sV6sLyOiVzxv0W_K2i8SOQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*sV6sLyOiVzxv0W_K2i8SOQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*VaZo5Kl6x-oLJOs9Id3pYg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*VaZo5Kl6x-oLJOs9Id3pYg.jpeg" /></p>

<p>日没後、振り返ってバスを待ち、松江へ戻る準備をしました。</p>

<h4 id="夕日指数">夕日指数</h4>

<p><img src="/assets/aacd5f5cacd1/1*gWAukxe8ynZEUN6Yr3-WAg.webp" alt="夕日指数は島根観光サイトを参考にできます" loading="lazy" decoding="async" width="1035" height="902" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDM1IiBoZWlnaHQ9IjkwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*gWAukxe8ynZEUN6Yr3-WAg.png" /></p>

<p><a href="https://tw.visit-matsue.com/sunset" target="_blank">夕陽指数は島根観光サイトを参考にしてください</a></p>

<h4 id="宍道湖遊覧船">宍道湖遊覧船</h4>

<p><img src="/assets/aacd5f5cacd1/1*owwW5fWHIBKb0PQU_gMqVg.webp" alt="&lt;https://hakuchougo.jp/timetable/&gt;" loading="lazy" decoding="async" width="1136" height="834" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTM2IiBoZWlnaHQ9IjgzNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*owwW5fWHIBKb0PQU_gMqVg.png" /></p>

<p><a href="https://hakuchougo.jp/timetable/" target="_blank">https://hakuchougo.jp/timetable/</a></p>

<p><a href="https://www.kankou-shimane.com/zh-tw/destinations/1086" target="_blank">宍道湖には遊覧船があります</a>。夕陽に近づく時間に乗って、船上から夕陽を楽しめます。次回訪れるときはぜひ乗ってみたいです。</p>

<p><img src="/assets/aacd5f5cacd1/1*RGoFqjg8YVZwTzpINu4PCQ.webp" alt="" loading="lazy" decoding="async" width="554" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*RGoFqjg8YVZwTzpINu4PCQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*nt2iPompX1qAecOKd_C7hA.webp" alt="" loading="lazy" decoding="async" width="1179" height="2556" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTc5IiBoZWlnaHQ9IjI1NTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*nt2iPompX1qAecOKd_C7hA.jpeg" /></p>

<blockquote>
  <p><em>直接購入したJRパスに付いてくる<a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank"><strong>山陰山陽エリアパス周遊3日券</strong></a><strong>を無料で利用でき、1,800円節約できます。</strong></em></p>
</blockquote>

<h4 id="1800-松江駅とホテルに戻る">18:00 松江駅とホテルに戻る</h4>

<h4 id="松江駅1階のお土産店でいくつかお土産を買う">松江駅1階のお土産店でいくつかお土産を買う</h4>

<p>山陰は少し特別なので、ここでお土産を買おうと思います。</p>

<p><img src="/assets/aacd5f5cacd1/1*gEdRChjcIYrXT_A8f6viyw.webp" alt="" loading="lazy" decoding="async" width="1144" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQ0IiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*gEdRChjcIYrXT_A8f6viyw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*fQj5GAdIRZ8uKKofUerGSw.webp" alt="" loading="lazy" decoding="async" width="1400" height="995" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*fQj5GAdIRZ8uKKofUerGSw.png" /></p>

<p>少し珍しいのは牛骨スープのラーメンで、通常は豚骨です。1箱買って台湾で味わいました。</p>

<p><img src="/assets/aacd5f5cacd1/1*n7-mvNNxKfjHJ7eNusg_Dg.webp" alt="" loading="lazy" decoding="async" width="1200" height="801" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*n7-mvNNxKfjHJ7eNusg_Dg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*vqDE5sO1mYFkzrYP2WNsZg.webp" alt="" loading="lazy" decoding="async" width="1400" height="937" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjkzNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*vqDE5sO1mYFkzrYP2WNsZg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*P175dGuAEKQkW-rvGbIIeg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*P175dGuAEKQkW-rvGbIIeg.jpeg" /></p>

<p>同僚に分けるために大きなクッキーの箱を2つ買いました。甘い方は普通ですが、出雲大社の参拝記念品です。塩味の海鮮せんべいクッキーはとても美味しいと思います！</p>

<h4 id="ホテルに戻る">ホテルに戻る</h4>

<p><img src="/assets/aacd5f5cacd1/1*kmBiT9EX6g-d743wStYgxQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*kmBiT9EX6g-d743wStYgxQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*9NE5tv23D6k51TvDFNEypw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*9NE5tv23D6k51TvDFNEypw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*MAHLZoAXHY9TYQO4fO8OEw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*MAHLZoAXHY9TYQO4fO8OEw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*VkEob5Q4_DKkVV14e67bQA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*VkEob5Q4_DKkVV14e67bQA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*e3EL2ltwD0nNVb2TbJzonQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*e3EL2ltwD0nNVb2TbJzonQ.jpeg" /></p>

<p>本館にはエレベーターがありません。予約したのは2号館で、本館のロビーから連絡通路を通って2号館に行けます。2号館の2階にはラウンジ、電子レンジ、ランドリー、販売機があります。</p>

<blockquote>
  <p><em>2号館はあまり安全な感じがしません。エレベーターに入退室制限がなく、<a href="https://www.cubic-room.jp/en/" target="_blank">1階と2階はカプセルホテル</a>なので出入りが複雑に感じられ、本館のロビーからも距離があります。そのため、チェックイン後は自分でスーツケースを使ってドアを塞ぎ、変な人が入ってこないようにしました。</em></p>
</blockquote>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/NLHi7arAioA" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p><img src="/assets/aacd5f5cacd1/1*jXAp31kbI-h2r6EC9p3GTg.webp" alt="" loading="lazy" decoding="async" width="1200" height="920" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkyMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*jXAp31kbI-h2r6EC9p3GTg.png" /></p>

<p>ロビーでは無料のフェイスマスク、コーヒー、ティーバッグがもらえます。</p>

<h4 id="食事探し">食事探し</h4>

<p><img src="/assets/aacd5f5cacd1/1*bXI0YIH7eaO7vZj8MaAfDA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*bXI0YIH7eaO7vZj8MaAfDA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*O6V7aJeRtLcN5NWwYYtEUw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*O6V7aJeRtLcN5NWwYYtEUw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*rNzPDu9gW2s89oW0oqxWSA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*rNzPDu9gW2s89oW0oqxWSA.jpeg" /></p>

<p>チェックイン後、外に食事を探しに行きました。外はかなり寒く、暗くて静かでした。すぐに駅周辺のレストランで弁当をテイクアウトし、コンビニで飲み物や食べ物を買ってホテルに戻りました。</p>

<p><img src="/assets/aacd5f5cacd1/1*FaaPod-j1hdncbRKhnNUOQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*FaaPod-j1hdncbRKhnNUOQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*UAYwYj0cNQZJsC99V7wq8A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*UAYwYj0cNQZJsC99V7wq8A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Oubxpe7aZ2GPBXI92NEMuQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Oubxpe7aZ2GPBXI92NEMuQ.jpeg" /></p>

<p>牛タン弁当は美味しく、コンビニで買った桃のスパークリングワインも美味しかったです。</p>

<blockquote>
  <p><em>おやすみ松江。</em></p>
</blockquote>

<p><strong>ほぼ毎日同じ翌日朝食セットも買いました…</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*YTezWlFUnTYd6qv1J-yjTw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YTezWlFUnTYd6qv1J-yjTw.jpeg" /></p>

<p>ファミリーマートのこの果肉入りジュースは、日本に来るたびに必ず飲みます！</p>

<h4 id="松江-宍道湖-24時間ライブ配信">松江 宍道湖 24時間ライブ配信：</h4>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/QYIjp0flsdQ" title="【LIVE】松江・宍道湖ライブカメラ" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>偶然見つけたYouTubeチャンネルで、宍道湖の天気や景色が見られます。</p>

<h3 id="day-3-1114-木曜日-松江堀川遊覧船松江城足立美術館">Day 3 (11/14 木曜日) 松江堀川遊覧船、松江城、足立美術館</h3>

<p>朝早に荷物をホテルに預けて、松江バス停からバスに乗り松江城の遊覧船へ行きました。</p>

<p><img src="/assets/aacd5f5cacd1/1*6Urhj-Bh4CXFgweozc99fQ.webp" alt="" loading="lazy" decoding="async" width="928" height="1183" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjgiIGhlaWdodD0iMTE4MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*6Urhj-Bh4CXFgweozc99fQ.png" /></p>

<p>Google マップではホームがわからず、現地で確認する必要があります。2番ホームの列車は松江城へ行けます。</p>

<p><img src="/assets/aacd5f5cacd1/1*xXKGKy95X00KjnN50FBzvw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*xXKGKy95X00KjnN50FBzvw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*gdwD77FXsNcNeaKz7NlXBQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*gdwD77FXsNcNeaKz7NlXBQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*4i5NFX226vWGW4yTEqOqIw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4i5NFX226vWGW4yTEqOqIw.jpeg" /></p>

<p>県民会館前で下車し、松江城へ向かって歩くと、駐車場のあたりで「堀川遊覧船」の乗り場が見えます。</p>

<h4 id="jrパスの有効化-山陰山陽エリアパス3日券-堀川遊覧船が無料で乗車可能">JRパスの有効化 <a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank"><strong>山陰山陽エリアパス3日券</strong></a> <strong>堀川遊覧船が無料で乗車可能</strong></h4>

<p><img src="/assets/aacd5f5cacd1/1*NKAYef5qS_1KVVW7sx2BKg.webp" alt="" loading="lazy" decoding="async" width="554" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTQiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*NKAYef5qS_1KVVW7sx2BKg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ksm-qt0AJ9qWES0k9HQ8-g.webp" alt="" loading="lazy" decoding="async" width="843" height="828" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NDMiIGhlaWdodD0iODI4Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*ksm-qt0AJ9qWES0k9HQ8-g.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*dBYTcpDfIH02XoGUtviyTQ.webp" alt="" loading="lazy" decoding="async" width="583" height="1261" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1ODMiIGhlaWdodD0iMTI2MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*dBYTcpDfIH02XoGUtviyTQ.png" /></p>

<ol>
  <li>
    <p>ダウンロード <a href="https://apps.apple.com/tw/app/discover-another-japan/id1530307213" target="_blank">Discover Another Japan App</a></p>
  </li>
  <li>
    <p>証明書メール内のシリアル番号をコピーする</p>
  </li>
  <li>
    <p>アプリを開き、「入力」を選んでシリアル番号を貼り付け、「有効化」を押す。</p>
  </li>
</ol>

<p><img src="/assets/aacd5f5cacd1/1*bXVG4mS9rEj5I2nV8hUpqQ.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*bXVG4mS9rEj5I2nV8hUpqQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*6s5mwpiKNIIC3bNIw48qjw.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*6s5mwpiKNIIC3bNIw48qjw.jpeg" /></p>

<p>「使用」に切り替えて健康問診票を記入すると、QRコード用のカメラが表示されます。店舗が提供するQRコードをスキャンして結果を見せれば、交換が完了します。</p>

<p>「目標内容」をクリックすると交換可能なアイテムを確認できます。</p>

<blockquote>
  <p><strong><em>実際の計算時間は最初に目標を交換した時点から開始</em></strong> <em>であり、シリアル番号を入力して有効化した時点（私は11月13日に入力しました）ではありません。</em></p>
</blockquote>

<p><strong>みなさんのために人気の利用可能場所をまとめました：</strong></p>

<ul>
  <li>
    <p>宍道湖遊覧船、定価1,800円</p>
  </li>
  <li>
    <p>松江城遊覧船、通常価格1,600円</p>
  </li>
  <li>
    <p>足立美術館、定価2,300円</p>
  </li>
  <li>
    <p>松江城、通常価格680円</p>
  </li>
  <li>
    <p>鳥取砂丘美術館、通常価格800円</p>
  </li>
  <li>
    <p>通天閣、通常価格800円</p>
  </li>
  <li>
    <p>岡山後楽園、通常価格410円</p>
  </li>
</ul>

<p>本当にお得で、上記だけで合計8,390円も節約でき、JRパスの金額の半分に相当します。</p>

<h4 id="0915-松江観光船に乗る">09:15 松江観光船に乗る</h4>

<p><img src="/assets/aacd5f5cacd1/1*yTUoyuDBmxnZi7Z-LW5scg.webp" alt="" loading="lazy" decoding="async" width="943" height="1191" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDMiIGhlaWdodD0iMTE5MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*yTUoyuDBmxnZi7Z-LW5scg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*D0KiYKloofkru6tcupBTWw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*D0KiYKloofkru6tcupBTWw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*0xbwCSI0IA7-pvoRwIhPVQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="852" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*0xbwCSI0IA7-pvoRwIhPVQ.png" /></p>

<p>直接<a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank">周遊3日券</a>で無料交換して乗車。</p>

<ul>
  <li>
    <p>今年は比較的暖かく、まだこたつ船にはなっていません。</p>
  </li>
  <li>
    <p>橋をくぐる際に4か所で船体を下げる必要があるため、手を挟まないよう注意してください。</p>
  </li>
  <li>
    <p>全行程は約50分です。</p>
  </li>
  <li>
    <p><strong>乗船時は靴を脱ぐ必要があります</strong> ⚠️</p>
  </li>
  <li>
    <p><strong>船頭に近く、船頭から離れるほど船頭に近い右側の列のみが松江城に接した景色を直接撮影できます（＝乗船したばかりの1列目の席）</strong> ⚠️ 下の写真の通り</p>
  </li>
</ul>

<p><img src="/assets/aacd5f5cacd1/1*NNpCqdpowVo3qcGUB2MtIA.webp" alt="" loading="lazy" decoding="async" width="963" height="1194" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjMiIGhlaWdodD0iMTE5NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*NNpCqdpowVo3qcGUB2MtIA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*mycuhLZJdCqQCLjmdKBVuA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*mycuhLZJdCqQCLjmdKBVuA.jpeg" /></p>

<p>乗船しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*OaajDPfbGMPtNGE45b0D7w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*OaajDPfbGMPtNGE45b0D7w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*pnqFPC8vK3sPGShIQY8vwg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*pnqFPC8vK3sPGShIQY8vwg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*_zTAi1v6rP1ObrmmGAyivw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_zTAi1v6rP1ObrmmGAyivw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*LqE3q-z47EBROFnfkCzONA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*LqE3q-z47EBROFnfkCzONA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*7hUFpDj5m7TYkRzY_QhrOA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*7hUFpDj5m7TYkRzY_QhrOA.jpeg" /></p>

<p>紅葉シーズンがまだ始まっていなかったためか、人は少なく、同じ船に乗っていたのは4人だけで、とても空いていました。</p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/1dP7cQcqkW8" title="松江堀川遊覽船過橋" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>橋を渡る際に船体が下がる4つの橋があり、少し腰をかがめて通過する必要があります。</p>

<p><img src="/assets/aacd5f5cacd1/1*f71WOF93FIEGnY_AFJ94OQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*f71WOF93FIEGnY_AFJ94OQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*CgP34NWi1KsKk8je60g2Aw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*CgP34NWi1KsKk8je60g2Aw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*mqX7jwzT8WnOhg9hwZKZPA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*mqX7jwzT8WnOhg9hwZKZPA.jpeg" /></p>

<p>川を風を感じながら進むのはとても気持ちよく、船頭さんも周囲の観光スポットや歴史を案内してくれました（ただ、私は「左（ひだり）」と「右（みぎ）」しかわかりませんでしたが…）。</p>

<p><img src="/assets/aacd5f5cacd1/1*vY1xPWmFrFq7m4ErBFYRAQ.webp" alt="&lt;https://youtube.com/shorts/KA9xKZV16bk&gt;" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*vY1xPWmFrFq7m4ErBFYRAQ.jpeg" /></p>

<p><a href="https://youtube.com/shorts/KA9xKZV16bk" target="_blank">https://youtube.com/shorts/KA9xKZV16bk</a></p>

<p>最後に帰路の近くに松江城の撮影スポットがあり、ここから松江城の遠景を撮影できます。</p>

<p>遊覧船は約10:00に終了しました。</p>

<h4 id="1015-松江城">10:15 松江城</h4>

<p><img src="/assets/aacd5f5cacd1/1*ceaDL6BSPF0gB-VCXOw3fA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ceaDL6BSPF0gB-VCXOw3fA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*KTDVdtsyThXmXZC0hlXqPQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*KTDVdtsyThXmXZC0hlXqPQ.jpeg" /></p>

<p>遊覧船から戻ってきて歩く方向の反対側に松江城の入口があり、そこから上に登ると松江城に着きます。</p>

<p><img src="/assets/aacd5f5cacd1/1*1zbsEA6XAM1EhL6AoGwyng.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*1zbsEA6XAM1EhL6AoGwyng.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*PNjiGAlCMJvOWEgPCi6Vrg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*PNjiGAlCMJvOWEgPCi6Vrg.jpeg" /></p>

<p>松江神社を通り過ぎて、松江城に到着しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*rrtm3CezY7W1ZWPIbj5p-A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*rrtm3CezY7W1ZWPIbj5p-A.jpeg" /></p>

<p>時間が限られていたため、足立美術館へは行かずに先に進みました。</p>

<p><img src="/assets/aacd5f5cacd1/1*9JAHlSW6QmLNzAWDU0-THA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*9JAHlSW6QmLNzAWDU0-THA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*XmGdiTwZJk7pWY95CCZkrQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*XmGdiTwZJk7pWY95CCZkrQ.jpeg" /></p>

<p>帰りは来た方向と反対の県民会館前バス停でバスを待って戻ります。</p>

<h4 id="1030-ホテルに戻って荷物を取る">~=10:30 ホテルに戻って荷物を取る</h4>

<p><img src="/assets/aacd5f5cacd1/1*z5o-twtGfhsaje84wIlhlA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*z5o-twtGfhsaje84wIlhlA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*cG2vaqw6VB1jXg2Eg78Jnw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*cG2vaqw6VB1jXg2Eg78Jnw.jpeg" /></p>

<p>大体10時30分に松江駅に戻り、ホテルで荷物を受け取ります。</p>

<blockquote>
  <p><strong><em>ここで信号待ちをしているとき、ブレーキの効かない自転車にぶつかりそうになりました。幸い、私は少し後ろに立っていたので当たりませんでした。外出時はやはり注意が必要です。</em></strong> <em>⚠️⚠️⚠️</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*J13Zlai29b-V7OR6-NSDuw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*J13Zlai29b-V7OR6-NSDuw.jpeg" /></p>

<p>駅に到着後、同様に「やくも14号」の指定席を予約して安来（安来）（足立美術館）へ向かいます。</p>

<h4 id="1103-安来へ向かう">11:03 安来へ向かう</h4>

<p><img src="/assets/aacd5f5cacd1/1*-eYBNFeXAXeaT3i73YPeRg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*-eYBNFeXAXeaT3i73YPeRg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*5JTFZNrBFGhSKo0M54Rwrg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*5JTFZNrBFGhSKo0M54Rwrg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*49TFnjK8AnLDrYCA-naQtw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*49TFnjK8AnLDrYCA-naQtw.jpeg" /></p>

<p>11:03に出発するので、駅の近くで軽食を買って車内で腹ごしらえ。</p>

<blockquote>
  <p><strong><em>さようなら松江。</em></strong></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*g-Sewe5VgTJrqioiNt32mw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*g-Sewe5VgTJrqioiNt32mw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*gCedzvZrVNY7_hfPkBBtEg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*gCedzvZrVNY7_hfPkBBtEg.jpeg" /></p>

<p>パンケーキと塩味のローストチキンはどちらもとても美味しかったです。</p>

<h4 id="1112-安来駅に到着">11:12 安来駅に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*6VLLQilNbIvambZZ2FqlTg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*6VLLQilNbIvambZZ2FqlTg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*fzfeXO1wERdPoGfoSeImew.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*fzfeXO1wERdPoGfoSeImew.jpeg" /></p>

<p>安来駅に着いたら、すぐに改札を出ずに、観光案内所を見つけて大型荷物を預けましょう。<br />
（駅の外にコインロッカーはありますが、ほとんど満杯です）</p>

<h4 id="1130-シャトルバスで足立美術館へ移動">11:30 シャトルバスで足立美術館へ移動</h4>

<p><img src="/assets/aacd5f5cacd1/1*BHs4S2OQTB2L5GC5beFFCQ.webp" alt="" loading="lazy" decoding="async" width="894" height="942" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4OTQiIGhlaWdodD0iOTQyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*BHs4S2OQTB2L5GC5beFFCQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Ng6cROhDXC8dFa-jX9Rr9g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Ng6cROhDXC8dFa-jX9Rr9g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ZGpQ1IE2Rs3sdSVHF4FKKw.webp" alt="最新の時刻表は公式サイトをご覧ください" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ZGpQ1IE2Rs3sdSVHF4FKKw.jpeg" /></p>

<p><a href="https://www.adachi-museum.or.jp/en/shuttle-bus" target="_blank">最新の時刻表は公式サイトをご参照ください</a></p>

<p>荷物を置いた後、足立美術館行きのシャトルバス（無料、並んだ順に乗車）に乗りに行きました。朝はあまり人がいませんでした。</p>

<p>田舎の小道を約20分歩いて足立美術館に到着します。</p>

<p><img src="/assets/aacd5f5cacd1/1*yWU0ZbZ-BplOe9PpE7gLKw.webp" alt="" loading="lazy" decoding="async" width="931" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzEiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*yWU0ZbZ-BplOe9PpE7gLKw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*EzIv3NLDJE4hVA0BgtIQoQ.webp" alt="" loading="lazy" decoding="async" width="947" height="1217" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDciIGhlaWdodD0iMTIxNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*EzIv3NLDJE4hVA0BgtIQoQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*dKhsS-vXIfeBwam-mmARTQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*dKhsS-vXIfeBwam-mmARTQ.jpeg" /></p>

<p>降りてからまっすぐ進むと足立美術館の入口です。</p>

<p><img src="/assets/aacd5f5cacd1/1*pNf0-7iKNi1tn50chXc1-w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*pNf0-7iKNi1tn50chXc1-w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ROq_9K0FNF31iLA7f-A5Ng.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ROq_9K0FNF31iLA7f-A5Ng.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Q_wkpK8esb5iKNWHxOf4vg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Q_wkpK8esb5iKNWHxOf4vg.jpeg" /></p>

<p>同様に<a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank">周遊3日券</a>を無料で引き換えて入場しました。</p>

<p>最初に、入口前のカウンターで自分の行程に合わせた「シャトルバス整理券」を一人一枚受け取ります。指定時間になったら、降車した場所に戻り、整理券を提示して安来駅行きのバスに乗ります。</p>

<p><img src="/assets/aacd5f5cacd1/1*mxWMQacl1bNSfdRo8X9JQA.webp" alt="" loading="lazy" decoding="async" width="923" height="1185" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjMiIGhlaWdodD0iMTE4NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*mxWMQacl1bNSfdRo8X9JQA.png" /></p>

<p>私の予定では14:46に安来発の鳥取行きJRに乗る予定です。<strong>鳥取行きの便は多くないのでご注意ください⚠️。</strong></p>

<blockquote>
  <p><strong><em>とても重要！とても重要！とても重要！必ず受け取ってください。そうしないと、座席が確保できる保証はありません。⚠️⚠️⚠️</em></strong></p>
</blockquote>

<blockquote>
  <p><em>チケットを取る必要があることに気づかず、13:00の電車に乗るつもりでしたが、券を取らなければならないとわかり、一度取りに戻ってから13:35の電車に乗って安来に戻りました。</em></p>
</blockquote>

<blockquote>
  <p><em>時間に余裕を持って計画していて良かった。</em></p>
</blockquote>

<h4 id="足立美術館--日本一の庭園">足立美術館 — 日本一の庭園</h4>

<p><img src="/assets/aacd5f5cacd1/1*P4YjMlS0gulw8Z9Jr4a2mA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*P4YjMlS0gulw8Z9Jr4a2mA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*cIY8_Z-eP8OSvK-NBQ8Rtw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*cIY8_Z-eP8OSvK-NBQ8Rtw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*bBghMwu_IRFmgbT7fW3EXw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*bBghMwu_IRFmgbT7fW3EXw.jpeg" /></p>

<p>ここに静かに座って庭園の景色を楽しむことができます。</p>

<p><img src="/assets/aacd5f5cacd1/1*l_vmr2dgh14H2GQ3LV3t4Q.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*l_vmr2dgh14H2GQ3LV3t4Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*U6yP0ur5hbX5RPLBCUJhOA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*U6yP0ur5hbX5RPLBCUJhOA.jpeg" /></p>

<p>庭園以外に、足立美術館の核心は多くの所蔵品であり、撮影は禁止されています。動線に沿って作品と庭園を鑑賞しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*wBCdJ9HmdU55eywoII8eZQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*wBCdJ9HmdU55eywoII8eZQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ftl17PV6R9Xvj6u_W2uTeg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*ftl17PV6R9Xvj6u_W2uTeg.jpeg" /></p>

<p>外から一部の庭園の景観が見え、手間と時間をかけてこの造園を維持していることが感じられます。</p>

<p><img src="/assets/aacd5f5cacd1/1*jNTMLjG2TDFOdTE4Sl72DA.webp" alt="" loading="lazy" decoding="async" width="945" height="1234" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDUiIGhlaWdodD0iMTIzNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*jNTMLjG2TDFOdTE4Sl72DA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*tcvXnD0yZU2J36q-7DFPPw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*tcvXnD0yZU2J36q-7DFPPw.jpeg" /></p>

<p>中には2軒の喫茶室があり、スイーツやコーヒーだけでなく軽食も販売しています。ここで休憩しながら景色を楽しむのもおすすめです。</p>

<blockquote>
  <p><em>一人旅だったので、特に食事のために立ち寄ることはありませんでした。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*r-y6_oqYcCr7gHBkO2htAw.webp" alt="" loading="lazy" decoding="async" width="1400" height="980" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*r-y6_oqYcCr7gHBkO2htAw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*P2G-cBOftGDBhXjRe93JmA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1009" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMDkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*P2G-cBOftGDBhXjRe93JmA.png" /></p>

<p>お土産屋で見かけた収蔵作品 <a href="https://artsandculture.google.com/asset/mt-fuji/gQGjCiwQOJy4bg?hl=zh-TW" target="_blank">横山大観《神国日本》(Yokoyama Taikan “Mt.Fuji”) の紙製複製画</a> を記念品として購入しました。</p>

<h4 id="1230-外の商店街をぶらぶらする">12:30 外の商店街をぶらぶらする</h4>

<p>外には小さな商店街があり、まだ時間が早かったので、とりあえずぶらぶら歩いてみました。</p>

<p><img src="/assets/aacd5f5cacd1/1*F0w3N5TCBhJnHxDTPKvIlw.webp" alt="" loading="lazy" decoding="async" width="942" height="1182" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDIiIGhlaWdodD0iMTE4MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*F0w3N5TCBhJnHxDTPKvIlw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*vUCovPlzvYxsnyfTqahbdg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*vUCovPlzvYxsnyfTqahbdg.jpeg" /></p>

<blockquote>
  <p><em>この島根和牛米バーガーは<strong>あまり美味しくなかった</strong>です。電子レンジで温めた米バーガーのご飯がべたついていて、私が食べた和牛はまだ完全に温まっておらず冷たかったです…</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*04ZXVwciPcQrHZaCi_mP_A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*04ZXVwciPcQrHZaCi_mP_A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*IIi5iKRgO4Z3X-WVGXSAlg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*IIi5iKRgO4Z3X-WVGXSAlg.jpeg" /></p>

<p>前述の通り、最初は整理券を取る必要があることを知らず、ぼんやりとバスを待っていました。13:00の便に乗れないと気づいてから、13:35の整理券を取りに行きました。</p>

<p><img src="/assets/aacd5f5cacd1/1*_qEUfX9ZPhw4e7GoCkd1mA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_qEUfX9ZPhw4e7GoCkd1mA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*CYcgaIGY63OyZ8AVqxp6zQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*CYcgaIGY63OyZ8AVqxp6zQ.jpeg" /></p>

<p>整理券を受け取って再入場（再入場可）し、最初の室内展望エリアに座って景色をぼんやり眺めながらバスを待つ。</p>

<h4 id="1355-安来駅に戻る">13:55 安来駅に戻る</h4>

<p><img src="/assets/aacd5f5cacd1/1*32LdARFSPE8UZX5Ncpp__Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*32LdARFSPE8UZX5Ncpp__Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*wiaNCbcWfMAr83dH_VyhVg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*wiaNCbcWfMAr83dH_VyhVg.jpeg" /></p>

<p>安来駅への道中で、とても赤い紅葉を見かけました。</p>

<p><img src="/assets/aacd5f5cacd1/1*hmDP79nt4683WCrugG3F6A.webp" alt="" loading="lazy" decoding="async" width="1200" height="848" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*hmDP79nt4683WCrugG3F6A.png" /></p>

<p>この時間帯に足立美術館に訪れる人の方がむしろ多いです。</p>

<p><img src="/assets/aacd5f5cacd1/1*pNI1d_ksSnexO0WKcSSLww.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*pNI1d_ksSnexO0WKcSSLww.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*9O3RZpisQ42q9L5HBVfK2w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*9O3RZpisQ42q9L5HBVfK2w.jpeg" /></p>

<p>この駅はあまり人がおらず、まだ時間も早かったので、<a href="https://www.youtube.com/shorts/oG8xrxEC6mk" target="_blank">JR Passで指定席を予約する方法を示した動画を撮影しました</a> 。</p>

<p><img src="/assets/aacd5f5cacd1/1*09Yg8-nz6BzwsrB4MboUmg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*09Yg8-nz6BzwsrB4MboUmg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*hgL7isSy3JI2ynErDWL-bw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*hgL7isSy3JI2ynErDWL-bw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*xtWvh1YCoprT8eqqP_uxoQ.webp" alt="島根猫" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*xtWvh1YCoprT8eqqP_uxoQ.jpeg" /></p>

<p><a href="https://www.kankou-shimane.com/shimanekko/zh-TW/" target="_blank">島根ねこ</a></p>

<p>観光案内所でぶらぶらして時間をつぶす。</p>

<p><img src="/assets/aacd5f5cacd1/1*90geto8qdEZ4we55uwzlmw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*90geto8qdEZ4we55uwzlmw.jpeg" /></p>

<p>安来の清水寺も紅葉の穴場スポットのように感じました。</p>

<p><img src="/assets/aacd5f5cacd1/1*ekgTftsMdymYawBX5WrRZw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ekgTftsMdymYawBX5WrRZw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*9UPTdrAVmNFfUTae3Z4jbQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*9UPTdrAVmNFfUTae3Z4jbQ.jpeg" /></p>

<h4 id="1446-特急列車で鳥取へ向かう">14:46 特急列車で鳥取へ向かう</h4>

<p><img src="/assets/aacd5f5cacd1/1*9xXAaj9MkAymGU2AgeaMKg.webp" alt="" loading="lazy" decoding="async" width="687" height="1177" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2ODciIGhlaWdodD0iMTE3NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*9xXAaj9MkAymGU2AgeaMKg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*4QAm8AK5zXIGMVeIjRc8sg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4QAm8AK5zXIGMVeIjRc8sg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*2gCmHxDsPcbPLcngamFmpg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*2gCmHxDsPcbPLcngamFmpg.jpeg" /></p>

<p>車両はとても古く、2両編成（自由席1両、指定席1両）しかありません。私の26インチのスーツケースは上の荷物棚に乗せられませんでした（新しいJR車両なら可能ですが、この車両の棚は小さすぎます）。最後尾の席の後ろに置けることを忘れていて、自分の席に無理やり置くしかありませんでした。</p>

<p>隣に誰もいなくてよかったです。自由席の車両はもっと混んでいるように見えましたが、指定席のこちらはまだ6割ほどの乗車率でした。</p>

<blockquote>
  <p><em>スケジュールの都合で、鬼太郎駅（境港駅）とコナン駅（由良駅）には特に行きませんでした。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*STYxvjU_ogrZ2fDlL9Y6ng.webp" alt="出典" loading="lazy" decoding="async" width="894" height="667" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4OTQiIGhlaWdodD0iNjY3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*STYxvjU_ogrZ2fDlL9Y6ng.png" /></p>

<p><a href="https://www.pref.tottori.lg.jp/289054.htm" target="_blank">出典</a></p>

<p><img src="/assets/aacd5f5cacd1/1*hZSjEq5-ijzcPGGte6C40g.webp" alt="出典" loading="lazy" decoding="async" width="875" height="595" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzUiIGhlaWdodD0iNTk1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*hZSjEq5-ijzcPGGte6C40g.png" /></p>

<p><a href="https://www.pref.tottori.lg.jp/289055.htm" target="_blank">出典</a></p>

<blockquote>
  <p><em>興味がある方はぜひ時間をたっぷり取って訪れてください。</em></p>
</blockquote>

<h4 id="1558-jr鳥取駅に到着">15:58 JR鳥取駅に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*oPupIuWiEBmo4l8oYjdXEg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*oPupIuWiEBmo4l8oYjdXEg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*BkBOsOOK3AJtMY4Fh4nWlw.webp" alt="" loading="lazy" decoding="async" width="946" height="1195" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDYiIGhlaWdodD0iMTE5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*BkBOsOOK3AJtMY4Fh4nWlw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*kGq-zyfiHwjuwxWFtSTlnA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*kGq-zyfiHwjuwxWFtSTlnA.jpeg" /></p>

<p>今夜のホテル <a href="https://www.toyoko-inn.com/china/search/detail/00046/" target="_blank"><strong>東横INN 鳥取駅南口</strong></a> に向かいます。北口にも東横INNがありますが、予約が取れませんでした。北口の方が商店街が賑やかです。</p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/d8wVYHG4zkA" title="東橫INN 鳥取站南口" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<h4 id="1700-鳥取亂逛">17:00 鳥取亂逛</h4>

<p><img src="/assets/aacd5f5cacd1/1*vHGHHoGQxbgvDqexHR0gLQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*vHGHHoGQxbgvDqexHR0gLQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*k3EiMwp0DAViTzXwjie4pw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*k3EiMwp0DAViTzXwjie4pw.jpeg" /></p>

<p>食事の時間まであと1時間あるので、先に近くのAEONに行ってみます。</p>

<p><img src="/assets/aacd5f5cacd1/1*4ZSUZ9tpUCmTPjwuSXtUBg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4ZSUZ9tpUCmTPjwuSXtUBg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*mOuFR0sVsVoQ1RxuPH3YlA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*mOuFR0sVsVoQ1RxuPH3YlA.jpeg" /></p>

<p>ほぼ18時頃、鳥取北口商店街付近まで歩いて食事を探しました。ここ数日は適当に食べていましたが、今日は少し良いレストランを探したいと思います。</p>

<p><img src="/assets/aacd5f5cacd1/1*UPSjd6gbL9TCVXl8qXLPvw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*UPSjd6gbL9TCVXl8qXLPvw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*_Qkjzr6Xf_PV642XoYTcgw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_Qkjzr6Xf_PV642XoYTcgw.jpeg" /></p>

<p>大通り沿いで評判の良い鳥取和牛のレストラン「<a href="https://maps.app.goo.gl/pSZF8bCsiRNJ4aSt6" target="_blank">肉料理 Nick</a>」を見つけて、鳥取和牛を味わってみました。平日だったせいか、私一人だけでした。</p>

<blockquote>
  <p><em>鳥取和牛は神戸牛や近江牛ほど有名ではありませんが、鳥取は<strong>日本の和牛文化の発祥地</strong>です。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*4fDg5JJ-GGjiV8AVasNE3A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4fDg5JJ-GGjiV8AVasNE3A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*sI_cXfEuxYrVLS6SUqDArQ.webp" alt="" loading="lazy" decoding="async" width="782" height="1143" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3ODIiIGhlaWdodD0iMTE0MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*sI_cXfEuxYrVLS6SUqDArQ.png" /></p>

<p>私が注文したのは「鳥取和牛ひつまぶし」、鳥取和牛の三種の食べ方ご飯で3,500円、価格は神戸牛よりずっと安いです。</p>

<p><img src="/assets/aacd5f5cacd1/1*2jNeW3RO6WBh83rZqe0ZNA.webp" alt="" loading="lazy" decoding="async" width="1400" height="998" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*2jNeW3RO6WBh83rZqe0ZNA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*qkqZMeWtQcobrIOS8mrBJw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*qkqZMeWtQcobrIOS8mrBJw.jpeg" /></p>

<p>鳥取和牛はとても柔らかいですが、牛肉の味はあまり強くなく、最初に純粋に和牛だけを食べるとあまり味が感じられません。</p>

<p><img src="/assets/aacd5f5cacd1/1*jkud_7mVWN_F6ALBWCj14g.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*jkud_7mVWN_F6ALBWCj14g.jpeg" /></p>

<p>二、三回目の食事に付いてくるスープをかけて、お茶漬けにするととても美味しいです。</p>

<h4 id="1830-お腹いっぱいで駅とホテルへ戻る">18:30 お腹いっぱいで駅とホテルへ戻る</h4>

<p><img src="/assets/aacd5f5cacd1/1*OyxvrME3X2vnxLFRhB_IwQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OyxvrME3X2vnxLFRhB_IwQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ZDMJBQeQx2jvWFpFmbhB9g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ZDMJBQeQx2jvWFpFmbhB9g.jpeg" /></p>

<p>ついでに翌日姫路行きの切符を購入しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*2v_BIl1Ho5wcJS0WYAuDGg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*2v_BIl1Ho5wcJS0WYAuDGg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*21KCGclvNLUL2WojrkxJMA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*21KCGclvNLUL2WojrkxJMA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*VJNLFfTTyZCRFH0kgSGL5w.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*VJNLFfTTyZCRFH0kgSGL5w.jpeg" /></p>

<p>帰りに夜食を買ってホテルで食べました。それとY1000ヤクルト1000も。今回は特に飲まなくてもよく眠れました…</p>

<blockquote>
  <p><em>おやすみ、鳥取。</em></p>
</blockquote>

<h3 id="day-4-1115-金曜日-白兎神社鳥取砂丘姫路">Day 4 (11/15 金曜日) 白兎神社、鳥取砂丘、姫路</h3>

<p>朝はまず白兎神社（縁結び）に参拝し、鳥取駅北口に戻ってバス総合案内所へ向かい、バスターミナルを抜けて後ろの4番乗り場でバスを待ちます。</p>

<p><img src="/assets/aacd5f5cacd1/1*XR70UqceYMl6CmDWivqTaQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*XR70UqceYMl6CmDWivqTaQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*mpW7ne5REM1X5yfOAa5m4A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*mpW7ne5REM1X5yfOAa5m4A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*JzTpCld7REqa-Rqt4UpkgA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*JzTpCld7REqa-Rqt4UpkgA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*KJUGKv9wIKoO7sDwEnTYIw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*KJUGKv9wIKoO7sDwEnTYIw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*z_BfpEdl3Z-O_QW6OfC4SA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*z_BfpEdl3Z-O_QW6OfC4SA.jpeg" /></p>

<p>Googleマップに従って、白兎海岸線の鹿野営業所41番に乗り、白兎神社前で下車してください。</p>

<blockquote>
  <p><strong><em>鳥取のバスは電子決済に対応しておらず、現金のみ利用可能です</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>鳥取のバスは電子決済に対応しておらず、現金のみ利用可能です</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>鳥取のバスは電子決済に対応しておらず、現金のみ利用可能です</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>あらかじめ小銭を用意するか、千円札を運転手のそばで両替してください。</em></strong> <em>⚠️⚠️⚠️</em></p>
</blockquote>

<blockquote>
  <p><em>運賃は約610円です。</em></p>
</blockquote>

<p>または先に鳥取駅で観光一日乗車券を購入したほうが割安です。</p>

<p><img src="/assets/aacd5f5cacd1/1*9cUeNishMRW8xDRs7-ri_Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*9cUeNishMRW8xDRs7-ri_Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*qHL6pCuXKRfxH86xFFs45g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*qHL6pCuXKRfxH86xFFs45g.jpeg" /></p>

<p>降車前に画面に表示された金額を投入します。私たちは始発駅から乗車し切符を持っていなかったので、最初の区間の一つ前の金額を支払いました。</p>

<h4 id="-0930-白兎神社に到着">~= 09:30 白兎神社に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*40gg6SkBkYmveH13l0nvXQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*40gg6SkBkYmveH13l0nvXQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*-PFzilV6gkDEpOvbXLbG_A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*-PFzilV6gkDEpOvbXLbG_A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*m33qZ2cJ4FwqBjkb-6IsAg.webp" alt="" loading="lazy" decoding="async" width="938" height="1194" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzgiIGhlaWdodD0iMTE5NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*m33qZ2cJ4FwqBjkb-6IsAg.png" /></p>

<p>降りた後、戻って歩道橋の方向へ進むと白兎神社の入口があります。</p>

<blockquote>
  <p><em>白兎神社は「因幡の白兎」の伝説に由来します。伝説によると、大国主命（出雲大社）が傷ついた白兎を助けて健康を回復させ、その白兎の祝福を受けて八上比売姫の愛を勝ち取ったと言われています。</em></p>
</blockquote>

<blockquote>
  <p><em>白兎神社は良縁と癒しの象徴であり、両社とも幸福と縁結びを祈願する神聖な意味を持っています。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*69iTu4F0VaHW07l992wjMA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*69iTu4F0VaHW07l992wjMA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*OFRxkKGCLjl2SPMHKOlgcA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OFRxkKGCLjl2SPMHKOlgcA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*eUPpPJUou85qulUku9cDVA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*eUPpPJUou85qulUku9cDVA.jpeg" /></p>

<p>神社までの距離は遠くありませんが、道にはたくさんのウサギの神像があり、縁結びの石でいっぱいです。</p>

<blockquote>
  <p><em>出雲大社にも因幡の白兎の像がたくさんありますが、私は撮影を忘れてしまいました。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*RKT2AGgUHkzeHVEP7OlkgA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*RKT2AGgUHkzeHVEP7OlkgA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*1awKOYwzIPQ5BHVD0OgePQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1awKOYwzIPQ5BHVD0OgePQ.jpeg" /></p>

<p>鳥居の上にも縁結びの石が積まれていました。</p>

<p><img src="/assets/aacd5f5cacd1/1*6JmuOYncQTNDnamDE8lhoA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*6JmuOYncQTNDnamDE8lhoA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*KCuCyqwlHaza-Kz1r2J2Pw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*KCuCyqwlHaza-Kz1r2J2Pw.jpeg" /></p>

<p>神社は全体的に大きくなく、参拝は約15〜20分で終わります。</p>

<p><img src="/assets/aacd5f5cacd1/1*E5qACETPs0VUTwxrsXGXlg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*E5qACETPs0VUTwxrsXGXlg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*l2_nfwxbvPJW78TGZAQdng.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*l2_nfwxbvPJW78TGZAQdng.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*_mqNm0k5ubWNxOFxlWaIuw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_mqNm0k5ubWNxOFxlWaIuw.jpeg" /></p>

<p>縁結びの石も500円で買って、像に置きました。</p>

<p><img src="/assets/aacd5f5cacd1/1*fvYIjtTDJYlLzG5Zi9eJJg.webp" alt="" loading="lazy" decoding="async" width="1200" height="844" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*fvYIjtTDJYlLzG5Zi9eJJg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*NFlQA9p4TtNZTg6oEcFi-w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*NFlQA9p4TtNZTg6oEcFi-w.jpeg" /></p>

<p><strong>私が買った因幡の白兎：</strong></p>

<ul>
  <li>
    <p>左側：出雲大社の外にあるお土産屋で買ったもの</p>
  </li>
  <li>
    <p>右側：白兎神社で購入したもの（詩みくじ付き）</p>
  </li>
</ul>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/HbxBcKkfCnk" title="一隻兔子爲何要招惹一群鯊魚？經歷過兩次的死而復生，他竟然迎娶了自己祖先的女兒！大國主神話\\|大國主\\|因幡之白兔\\|根之囯\\|日本神話\\|蘭爸爸說故事" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>因幡の白兎と大国主神の物語。</p>

<h4 id="-0950-白兎神社外観案内所白兎ビーチ">~= 09:50 白兎神社外観案内所、白兎ビーチ</h4>

<p><img src="/assets/aacd5f5cacd1/1*OElc39nUjmOmxt1b2l_8vQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OElc39nUjmOmxt1b2l_8vQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*y-ATn5pE43fRSQoNCQKHAA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*y-ATn5pE43fRSQoNCQKHAA.jpeg" /></p>

<p>観光案内所には本当に白いウサギが飼われていて、食べ物やお土産も売っていました。パンを買ってお腹を満たしました。</p>

<p><img src="/assets/aacd5f5cacd1/1*HHmrUUqcvXrDsCAvzyOkAw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*HHmrUUqcvXrDsCAvzyOkAw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*bs7k1F-QNASY8qe7v9HFzQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*bs7k1F-QNASY8qe7v9HFzQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ayrC4DXTeXmXI1axNs29CA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ayrC4DXTeXmXI1axNs29CA.jpeg" /></p>

<p>白兎海岸はとても寂しいです。</p>

<p><img src="/assets/aacd5f5cacd1/1*yGwYlF_RqRc9JJ6wMFmjug.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*yGwYlF_RqRc9JJ6wMFmjug.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*rXW71tg5gJziOeVd5X3iRw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*rXW71tg5gJziOeVd5X3iRw.jpeg" /></p>

<p>バスは10:45まで鳥取駅方面行きがありません。もっと早い時間に来て早いバスに乗るほうが時間を節約できて良いと思います。</p>

<p><img src="/assets/aacd5f5cacd1/1*JfxN2JQq74dWK90Tsor_YQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*JfxN2JQq74dWK90Tsor_YQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*PuL80Noe3RS2fR-rkUF8vg.webp" alt="from: 圣炜" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*PuL80Noe3RS2fR-rkUF8vg.jpeg" /></p>

<p>from: 圣炜</p>

<blockquote>
  <p><strong><em>乗車時には必ず整理券をお取りください。整理券には番号が記載されており、降車時にその番号に対応した金額の硬貨と一緒に整理券を投入します。</em></strong> <em>⚠️</em></p>
</blockquote>

<p>車内で中国福建省から来た観光客に出会いました。彼の行程は私とちょうど逆で、先に姫路に行き、その後島根に行くそうです。お互いにおすすめの観光地を紹介し合い、彼は姫路ではまず書写山円教寺に行き、その後姫路城の写真スポットで撮影することを勧めてくれました。</p>

<blockquote>
  <p><strong><em>彼に感謝！最後に訪れて本当に価値があると感じました。</em></strong></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*ItWdhOq9YNwojhJt9l1pgA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*ItWdhOq9YNwojhJt9l1pgA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ZRMhH7FMc8ypC3jQoBKqkA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*ZRMhH7FMc8ypC3jQoBKqkA.jpeg" /></p>

<p>相生町で下車し、向かい側のバス停で鳥取砂丘方面行きのバスに乗り換えます。</p>

<p><img src="/assets/aacd5f5cacd1/1*3hf1z-tdcV_FVh_wW9JSKw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*3hf1z-tdcV_FVh_wW9JSKw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*UjpATzEo91FX4Ptdxtlb4g.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*UjpATzEo91FX4Ptdxtlb4g.jpeg" /></p>

<p>乗ったこの便は砂丘東口で降りて、そこから歩いて上がります。</p>

<blockquote>
  <p><em>乗車整理券で3番を受け取り、降車時に画面で3番に対応する金額を確認して投入します。この場合は250円を投入します。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*b3fTmvHBaj__OiMbjr5BpA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*b3fTmvHBaj__OiMbjr5BpA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*KGIqShdtrpqRYB31M253yQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*KGIqShdtrpqRYB31M253yQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*wiMKI8135q9TNJcrhuWiZQ.webp" alt="私の混乱した見学ルート。" loading="lazy" decoding="async" width="1200" height="917" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkxNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*wiMKI8135q9TNJcrhuWiZQ.png" /></p>

<p>私の混乱した見学ルート。</p>

<p>降りてから振り返り、分かれ道の案内に従って上へ進み、鳥取砂丘美術館を通り過ぎて鳥取砂丘の入口へ向かいます。</p>

<p><img src="/assets/aacd5f5cacd1/1*FOByNsR18dk-tExeF5VPUw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*FOByNsR18dk-tExeF5VPUw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*M1l7figNu-hmgZAbR_xjaw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*M1l7figNu-hmgZAbR_xjaw.jpeg" /></p>

<blockquote>
  <p><em>鳥取砂丘での禁止事項、<strong>特に砂の上に絵を描く行為は禁止されており、自然を損なうことは厳禁です</strong>。⚠️</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*UCu5KdaTZWThGBgaSompbg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*UCu5KdaTZWThGBgaSompbg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*87V9nbswSrqQfx3JcDcVYQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*87V9nbswSrqQfx3JcDcVYQ.jpeg" /></p>

<p>鳥取砂丘は本当に広いです。この時はあいにくの曇り雨でしたが、晴天だとかなり日差しが強いと思います。</p>

<h4 id="1200-鳥取砂丘に到着">~=12:00 鳥取砂丘に到着</h4>

<p>日本一の砂丘。</p>

<p><img src="/assets/aacd5f5cacd1/1*WkiGJSHcUrPZi5h7zSJGYA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*WkiGJSHcUrPZi5h7zSJGYA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*lwqbSawD2wG3wO1MyAf2Bg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*lwqbSawD2wG3wO1MyAf2Bg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*NEuDeBgnNxtTSaYVQCd2NQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*NEuDeBgnNxtTSaYVQCd2NQ.jpeg" /></p>

<p>人はとても小さく見え、砂丘の尾根まで歩くと少し震え、砂が緩くて歩きにくかったです。</p>

<p><img src="/assets/aacd5f5cacd1/1*Gu98SJFPwWWKTj5PQR0zUw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Gu98SJFPwWWKTj5PQR0zUw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*S44sCcfn1C1zx3--fIIoBw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*S44sCcfn1C1zx3--fIIoBw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*w0d4u78ensGTedfoTINN4g.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*w0d4u78ensGTedfoTINN4g.jpeg" /></p>

<p>最高地点まで歩くと、海岸線全体を見渡せます。砂丘の背後に海が広がる景色はここだけです。</p>

<p><img src="/assets/aacd5f5cacd1/1*B-Oqyt2XYx4TVTMblCdEdw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1008" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*B-Oqyt2XYx4TVTMblCdEdw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*9ZoPtPjdHz3aaFTGNDT8iw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*9ZoPtPjdHz3aaFTGNDT8iw.jpeg" /></p>

<p>ネットで調べたらラクダに乗れるようですが、今日は天気が悪いためか乗れませんでした。</p>

<p><img src="/assets/aacd5f5cacd1/1*9WiZqF_alWi6M1PrHwG3sg.webp" alt="" loading="lazy" decoding="async" width="1400" height="994" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk5NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*9WiZqF_alWi6M1PrHwG3sg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*JxF65EE6eeACd1uRENVwNQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*JxF65EE6eeACd1uRENVwNQ.jpeg" /></p>

<p>最後に鳥取砂丘を離れるとき、もう一度振り返ってみると、本当に大きかったです。靴の中にも少し砂が入ってしまいましたが、<strong>プラスチックの靴カバーを直接はめている人がいて、とても賢いと思いました。</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*6cq3xUwokLToOCx38TXV9g.webp" alt="" loading="lazy" decoding="async" width="946" height="1199" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDYiIGhlaWdodD0iMTE5OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*6cq3xUwokLToOCx38TXV9g.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*OacuYCefS-wThnPRbo49xw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OacuYCefS-wThnPRbo49xw.jpeg" /></p>

<p>ここから直接ケーブルカーで鳥取砂丘展望台に行けますが、有名な鳥取第一砂丘プリンを下で先に食べたかったので乗りませんでした。後でついでに歩いて登りましたが、距離は遠くなく（約15分程度）でした。</p>

<p><img src="/assets/aacd5f5cacd1/1*SkKPyRhs_REhQrWDiLluNQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*SkKPyRhs_REhQrWDiLluNQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*30ZIWteqj87esh4ptH2w7A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*30ZIWteqj87esh4ptH2w7A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*6LhlMpfWyszDfyJ7PTf1vQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*6LhlMpfWyszDfyJ7PTf1vQ.jpeg" /></p>

<p>駐車場から出ると、対面に隈研吾が手掛けた鳥取砂丘の「Takahama Cafe 高濱カフェ」が見えます。</p>

<p><img src="/assets/aacd5f5cacd1/1*3OinDP-RDFHBQHLpY0olPw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*3OinDP-RDFHBQHLpY0olPw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*iGxKRD9KvMZrGuuHEjGNcA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*iGxKRD9KvMZrGuuHEjGNcA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YA0J3gRmOPgWhacPYV0LEg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*YA0J3gRmOPgWhacPYV0LEg.jpeg" /></p>

<p>試しに買ってみたら、味が本当に良くて、プリンのミルク味が濃厚で、食感はチーズケーキのようでした。</p>

<p><img src="/assets/aacd5f5cacd1/1*cRVlgCNRJysVUNkOkCHgFg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*cRVlgCNRJysVUNkOkCHgFg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*TafJZGPlGd5gft3gYj8Q3A.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*TafJZGPlGd5gft3gYj8Q3A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*sF3liqjkM6eQ6KURqwEfxA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*sF3liqjkM6eQ6KURqwEfxA.jpeg" /></p>

<p>特徴は、砂のような砂糖が小袋で付いてきて、一緒にかけて食べることです。</p>

<p><img src="/assets/aacd5f5cacd1/1*qOmSScKgkmuIBhtPJKcbiA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*qOmSScKgkmuIBhtPJKcbiA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*hv6d0AdzA-Ubx4XTqW8ZXQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*hv6d0AdzA-Ubx4XTqW8ZXQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*30_-rtFKE2Az1z6ikKIOSg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*30_-rtFKE2Az1z6ikKIOSg.jpeg" /></p>

<p>ここにはいくつかのレストランもあり食事ができます。さらに戻ると小道があり、少し上ると右手に砂丘美術館の第二入口があります。左手をもう少し上ると、さっきケーブルカーが到着した「鳥取砂丘展望台」です。</p>

<p><img src="/assets/aacd5f5cacd1/1*D9v4msXBz0mfsAWzXugtTw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*D9v4msXBz0mfsAWzXugtTw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*N9shdulrUJo5pphjg4lKMw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*N9shdulrUJo5pphjg4lKMw.jpeg" /></p>

<p>まず左側に向かい、鳥取砂丘展望台で景色を見たり食べ物を楽しんだりします。ロープウェイの乗り降り場所に先に到着します。</p>

<p><img src="/assets/aacd5f5cacd1/1*mo37aWPygCHfl-dAetnVQg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*mo37aWPygCHfl-dAetnVQg.jpeg" /></p>

<p>まずは販売所とその隣でブラシを使って靴の砂を落としましょう。（入口のスタッフも声をかけてくれます）</p>

<p><img src="/assets/aacd5f5cacd1/1*gTZJLV-MjOhVf3kxsPHwmg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*gTZJLV-MjOhVf3kxsPHwmg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*lQX5yEbrhiEqUxf6ekViVw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*lQX5yEbrhiEqUxf6ekViVw.jpeg" /></p>

<p>最後にここでバスを待って鳥取へ戻りました。</p>

<p><img src="/assets/aacd5f5cacd1/1*Re9IYuYqgtJre9oHgws_aA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*Re9IYuYqgtJre9oHgws_aA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*GLQ1-BDnEqB25ZBp2X3BAA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*GLQ1-BDnEqB25ZBp2X3BAA.jpeg" /></p>

<p>展望台の1階と2階はお土産売り場と小さなレストランがあり、3階は鳥取砂丘を眺めることができます（あまりよく見えませんが）。</p>

<p><img src="/assets/aacd5f5cacd1/1*fyEhTboh7RX-ZXqz9-FCPw.webp" alt="" loading="lazy" decoding="async" width="1200" height="868" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*fyEhTboh7RX-ZXqz9-FCPw.png" /></p>

<p>中の食事の選択肢はあまり多くなく、先に隣の自動販売機で対応するセット券を購入し、入場して席を見つけたら券をスタッフに渡すだけです。</p>

<p>適当に牡蠣のセットを食べました。</p>

<p><img src="/assets/aacd5f5cacd1/1*bN0RPnkejfCFjKjmcGwNCw.webp" alt="" loading="lazy" decoding="async" width="1071" height="873" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDcxIiBoZWlnaHQ9Ijg3MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*bN0RPnkejfCFjKjmcGwNCw.png" /></p>

<p>ここでも鳥取のお土産をいくつか買いました。</p>

<h4 id="1330-砂丘美術館">13:30 砂丘美術館</h4>

<p><img src="/assets/aacd5f5cacd1/1*30_-rtFKE2Az1z6ikKIOSg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*30_-rtFKE2Az1z6ikKIOSg.jpeg" /></p>

<p>お腹がいっぱいになったら、2番入口から下に降りて砂丘美術館を散策します。（同じく<a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank"><strong>周遊3日券</strong></a>で<strong>無料入場</strong>）</p>

<p><img src="/assets/aacd5f5cacd1/1*Y_ybpatDG6ffIfa3CDMm8g.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*Y_ybpatDG6ffIfa3CDMm8g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*OvdkGmr4yDdAyhW9XwMMaQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OvdkGmr4yDdAyhW9XwMMaQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*BBkrd9MBZZdcAEwYz8gYxw.webp" alt="" loading="lazy" decoding="async" width="1200" height="843" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*BBkrd9MBZZdcAEwYz8gYxw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*NALOYc1jrxf6O7nYgweBvg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1184" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjExODQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*NALOYc1jrxf6O7nYgweBvg.png" /></p>

<p>2番入口から入ると、外の砂の彫刻から見学を始め、3階から2階へと下りながら進みます。実際には館内の砂の彫刻作品は2階のみで、施設はそれほど大きくありません。もし無料でなければ、多分入らなかったでしょう。</p>

<p><img src="/assets/aacd5f5cacd1/1*bRQIVt04vcixxfHrHh2_yg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*bRQIVt04vcixxfHrHh2_yg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*W01cTTu7FAgiW_zJRAeo-g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*W01cTTu7FAgiW_zJRAeo-g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*WZLGVTQPbJoyEK5-cZG7NQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*WZLGVTQPbJoyEK5-cZG7NQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*LiBlPyu3seaWbMkGm0eBnw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*LiBlPyu3seaWbMkGm0eBnw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*SnJ5-b_QTJ19ATurPLHEpw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*SnJ5-b_QTJ19ATurPLHEpw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*rubP2uOF0-o0QdJsoBzSWg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*rubP2uOF0-o0QdJsoBzSWg.jpeg" /></p>

<p>会場は小さいですが、各砂像の細部までとても精巧です。</p>

<p><img src="/assets/aacd5f5cacd1/1*GRvwUBqcwGumVvkL8utiJw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*GRvwUBqcwGumVvkL8utiJw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*lB74w9zvrdIiJBqpIIIT7g.webp" alt="" loading="lazy" decoding="async" width="686" height="881" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2ODYiIGhlaWdodD0iODgxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*lB74w9zvrdIiJBqpIIIT7g.png" /></p>

<p>もう一つ、面白い砂丘美術館のQRコードもスキャンできます。</p>

<p><img src="/assets/aacd5f5cacd1/1*uH_T1z2iVu4fs6XPKwCstg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*uH_T1z2iVu4fs6XPKwCstg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*K7XJXE5cRDMV7MYzrVybIQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*K7XJXE5cRDMV7MYzrVybIQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*lZu_yUKJOB44L4wuG04uRA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*lZu_yUKJOB44L4wuG04uRA.jpeg" /></p>

<p>一周りしてから、さっきの鳥取砂丘展望台に戻り、あちこち散策しながら鳥取梨のアイスクリームを食べました。14:20頃にバス停で待ち、14:42発の鳥取駅行きのバスに乗りました。</p>

<blockquote>
  <p><em>この駅から鳥取へ戻るバスは来た時点でほぼ満員で、無理やり乗り込みました。時間があれば、前の駅から乗る方が良いかもしれません。</em></p>
</blockquote>

<h4 id="202501-更新">2025/01 更新</h4>

<p>帰ってから知りましたが、鳥取は交通が不便なため、タクシー貸切の1日観光プランが提供されています。<a href="https://chugoku.letsgojp.com/archives/661034" target="_blank">詳細は観光案内所またはこちらのサイトをご参照ください</a> 。</p>

<h4 id="1510-鳥取駅に戻る">15:10 鳥取駅に戻る</h4>

<p><img src="/assets/aacd5f5cacd1/1*zD1KRkIAiYp-wtxk48AogA.webp" alt="" loading="lazy" decoding="async" width="704" height="1176" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDQiIGhlaWdodD0iMTE3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*zD1KRkIAiYp-wtxk48AogA.png" /></p>

<p>15:10頃に鳥取駅に戻り、この時点で雨が降り始めました。</p>

<p><img src="/assets/aacd5f5cacd1/1*7Ex8903aKslRQc4IpfH6GA.webp" alt="" loading="lazy" decoding="async" width="949" height="1189" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDkiIGhlaWdodD0iMTE4OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*7Ex8903aKslRQc4IpfH6GA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*cfJLhRhuQjLhQqWfzVqgFA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*cfJLhRhuQjLhQqWfzVqgFA.jpeg" /></p>

<p>駅のショップをぶらぶらしていたら、ここのお土産屋さんでも砂丘プリンを売っていました！</p>

<p><img src="/assets/aacd5f5cacd1/1*HyBzvP9I1y2YC4KbxyLr0w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*HyBzvP9I1y2YC4KbxyLr0w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*-Q6nYvGZP-PBIgMdW6Lk2A.webp" alt="" loading="lazy" decoding="async" width="637" height="432" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MzciIGhlaWdodD0iNDMyIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*-Q6nYvGZP-PBIgMdW6Lk2A.jpeg" /></p>

<p>もともと鳥取の有名なすなば珈琲に行くつもりでしたが、午後3時過ぎにはもう閉店していたので、駅内でnana’s green teaを見つけて、デザートとコーヒーを注文して休憩しました（人もスマホも充電が必要でした）。</p>

<p><img src="/assets/aacd5f5cacd1/1*a6nZx2RTbeZAsTfxOvTPKw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*a6nZx2RTbeZAsTfxOvTPKw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*UrMfxX9LNlDIR7suza8tCQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*UrMfxX9LNlDIR7suza8tCQ.jpeg" /></p>

<p>店内は快適でほとんど人がいません。</p>

<p><img src="/assets/aacd5f5cacd1/1*5os6rpDnUSjttVgCpigSRA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*5os6rpDnUSjttVgCpigSRA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*4RdqbhEiL0vrRwrMKnIXLw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4RdqbhEiL0vrRwrMKnIXLw.jpeg" /></p>

<p>わらび餅＋アイスクリーム＋ホットコーヒー、とても満足です。</p>

<h4 id="1615-ホテルに戻って荷物を取り再び駅で電車を待つ">16:15 ホテルに戻って荷物を取り、再び駅で電車を待つ</h4>

<p><img src="/assets/aacd5f5cacd1/1*UHCBHtR1kg15a4alJuXYlw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*UHCBHtR1kg15a4alJuXYlw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*i5dxFrKSOdkjH9186Q9nQA.webp" alt="" loading="lazy" decoding="async" width="931" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzEiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*i5dxFrKSOdkjH9186Q9nQA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*zlhp1-kuQp679hHmnFJE-g.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*zlhp1-kuQp679hHmnFJE-g.jpeg" /></p>

<p>まだ時間が早いので、16:55発の特急スーパー白兎で姫路へ向かいます。</p>

<p><img src="/assets/aacd5f5cacd1/1*8UmhqEYZA-9f5gzPNnhsiQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*8UmhqEYZA-9f5gzPNnhsiQ.jpeg" /></p>

<p>待ち時間にコナン列車を見かけました。</p>

<h4 id="1655-姫路行きの電車に乗車">16:55 姫路行きの電車に乗車</h4>

<blockquote>
  <p><strong><em>さようなら山陰。</em></strong></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*-Xupoj1iDwTdGF6ofS94Dw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*-Xupoj1iDwTdGF6ofS94Dw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*yVwbXNEx2C4NV80hjdj3uA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*yVwbXNEx2C4NV80hjdj3uA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*j3SvEKoIHa7lEXyq5_jcxA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*j3SvEKoIHa7lEXyq5_jcxA.jpeg" /></p>

<p>グリーン車の最前列の席を取れて、とても快適でした。</p>

<blockquote>
  <p><strong><em>荷物は車内が揺れるため上に置かず、思い切って最後列の座席まで歩いて行き、最後列の座席の後ろに横向きに置きました。</em></strong></p>
</blockquote>

<h4 id="1827-姫路駅に到着">18:27 姫路駅に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*3jfwcI6yLbuWuWzDM4mC8A.webp" alt="" loading="lazy" decoding="async" width="708" height="1190" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDgiIGhlaWdodD0iMTE5MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*3jfwcI6yLbuWuWzDM4mC8A.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*OdglmUjNMHHemWGLuppg3g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OdglmUjNMHHemWGLuppg3g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*XbSKEhcwPLxItxqUXd6CVg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*XbSKEhcwPLxItxqUXd6CVg.jpeg" /></p>

<p>ちょうど彼らの議員選挙に遭遇し、駅の外では議員が演説をしていて、多くの人が集まっていました。</p>

<p><img src="/assets/aacd5f5cacd1/1*9HmKh497akO8a6922Z7kLA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*9HmKh497akO8a6922Z7kLA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*uBit7SVmrOOBDLSPv9IEGw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*uBit7SVmrOOBDLSPv9IEGw.jpeg" /></p>

<p>出駅後、直接ホテルの<a href="https://www.toyoko-inn.com/china/search/detail/00317/" target="_blank"><strong>東横INN 姫路駅新幹線北口</strong></a>へ。最後の3泊はここに宿泊。北口側の東横INNは賑やかです。地図上は近く見えますが、実際に歩くと少し距離があり、約10分かかります。</p>

<p><img src="/assets/aacd5f5cacd1/1*VT_z6TemLvMX-ujCfUewiQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*VT_z6TemLvMX-ujCfUewiQ.jpeg" /></p>

<p>14階の最上階の部屋に割り当てられ、窓からの眺めがとても良かったです。</p>

<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/fAnO4AoRX-Q" title="東橫INN 姬路站新幹線北口" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<iframe class="embed-video" loading="lazy" src="https://www.youtube.com/embed/xl9eOyv4A-I" title="東橫INN 姬路站新幹線北口 14 樓窗外鐵路景觀" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>窓の外から姫路駅の線路を振り返って見ることができ、電車が通るとわずかに軌道音がしますが、夜になると電車はもう来ません。</p>

<h4 id="1900-ぶらっと外出して食事を探す">19:00 ぶらっと外出して食事を探す</h4>

<p>外に出て姫路城の夜景を見て、とても綺麗だと思いました。なぜか姫路城まで歩いて夜景を撮りに行こうと思ってしまいましたが、近すぎてうまく撮れず、あまり写真を撮らずにすぐに帰りました。道中は寒くてお腹も空いていたので、素直にすぐご飯を食べに行けばよかったです。</p>

<p><img src="/assets/aacd5f5cacd1/1*dy69JBLXC40kKDIYB3adGw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*dy69JBLXC40kKDIYB3adGw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*dyjiO-KVxTv99UskMZs9Ag.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*dyjiO-KVxTv99UskMZs9Ag.jpeg" /></p>

<p>姫路城は駅から約1キロ離れており、往復で約30分歩きました。</p>

<p><img src="/assets/aacd5f5cacd1/1*hEbq2RVL18Yscc-y9ozE8g.webp" alt="&lt;https://himeji-kyoukasuigetsu.com/en/&gt;" loading="lazy" decoding="async" width="1400" height="1040" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*hEbq2RVL18Yscc-y9ozE8g.png" /></p>

<p><a href="https://himeji-kyoukasuigetsu.com/en/" target="_blank">https://himeji-kyoukasuigetsu.com/en/</a></p>

<p><img src="/assets/aacd5f5cacd1/1*KLFCGcyq_F3ZVnM4w_GK2w.webp" alt="&lt;https://himeji-kyoukasuigetsu.com/en/&gt;" loading="lazy" decoding="async" width="1042" height="1059" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDQyIiBoZWlnaHQ9IjEwNTkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*KLFCGcyq_F3ZVnM4w_GK2w.png" /></p>

<p><a href="https://himeji-kyoukasuigetsu.com/en/" target="_blank">https://himeji-kyoukasuigetsu.com/en/</a></p>

<blockquote>
  <p><strong><em>今回は姫路城の冬季ライトアップイベントを逃してしまいましたが、とても綺麗でロマンチックだと思います。次の機会にまた訪れたいです。</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>イベント期間は2024年11月22日（金）から2025年2月23日（日）までです。</em></strong></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*tnvYT7YGcklotJdPdfpY8w.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*tnvYT7YGcklotJdPdfpY8w.jpeg" /></p>

<p>最後に、駅の北口2階のこの展望台から姫路城を撮るのが最適な場所だと分かりました。</p>

<p><img src="/assets/aacd5f5cacd1/1*dRxfkrBM2x_gMgusOlnZ5A.webp" alt="" loading="lazy" decoding="async" width="1036" height="861" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDM2IiBoZWlnaHQ9Ijg2MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*dRxfkrBM2x_gMgusOlnZ5A.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*zCHRn2ZG88rg_a7WnfXz1g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*zCHRn2ZG88rg_a7WnfXz1g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Pqy-Rk3t-bA36QHoaNrTPg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Pqy-Rk3t-bA36QHoaNrTPg.jpeg" /></p>

<p>夕食を買う前に、姫路駅の百貨店<a href="https://www.jrw-urban.co.jp/piole-himeji/tw" target="_blank">Piole Himeji</a>で少し散策し、ガチャガチャを楽しみました。</p>

<h4 id="2000-夕食を買って帰る">~=20:00 夕食を買って帰る</h4>

<p><img src="/assets/aacd5f5cacd1/1*8hgCoDK6cgGQJT4re9WRAA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*8hgCoDK6cgGQJT4re9WRAA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*piFnI5vcIs2l8lG5gQZRdg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*piFnI5vcIs2l8lG5gQZRdg.jpeg" /></p>

<p>2階の連絡橋を渡って隣のTERASSOへ行き、まだ閉まっていない焼肉店を見つけて焼肉弁当をテイクアウトし、ホテルで食べました。</p>

<p><img src="/assets/aacd5f5cacd1/1*PfaI0llzUMpwdqEzyz5iPg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*PfaI0llzUMpwdqEzyz5iPg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*vGLx0HKICVp2XggRVuXvQQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*vGLx0HKICVp2XggRVuXvQQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*V_AQ9WNRUuMFogArfhYn_g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*V_AQ9WNRUuMFogArfhYn_g.jpeg" /></p>

<p>途中でコンビニに寄って、食べ物や飲み物を買いました。</p>

<p><img src="/assets/aacd5f5cacd1/1*VfGo_hbbLnLFXz2wdnLF4A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*VfGo_hbbLnLFXz2wdnLF4A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*x3_zZ9A0QkjHdWDNkjuQqg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*x3_zZ9A0QkjHdWDNkjuQqg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*1nvfzK3jA2eVr-tTRIAUBw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1nvfzK3jA2eVr-tTRIAUBw.jpeg" /></p>

<p>お腹いっぱい食べてお風呂に入った後、下に降りて洗濯をしました。今回は東横インが洗剤持参が必要だと知っていたので、先にコインで洗濯用粉を買い、服と一緒に洗濯機に入れました。このホテルの乾燥機はとても新しくて高性能で、温度も選べます。</p>

<p><img src="/assets/aacd5f5cacd1/1*1b9IFBlF0z6jwwChXs1zPg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1b9IFBlF0z6jwwChXs1zPg.jpeg" /></p>

<blockquote>
  <p><strong><em>おやすみ、姫路。</em></strong></p>
</blockquote>

<h3 id="5日目1116-土書写山円教寺姫路城姫路周辺ショッピング">5日目（11/16 土）書写山円教寺、姫路城、姫路周辺ショッピング</h3>

<p><img src="/assets/aacd5f5cacd1/1*EqvQAU91nnYsl8w7vT7CTg.webp" alt="" loading="lazy" decoding="async" width="1200" height="851" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*EqvQAU91nnYsl8w7vT7CTg.png" /></p>

<p>東横INNはどの店舗も無料の朝食を提供していますが、私はスケジュールが忙しくて、朝はほとんど前日の夜に買ったコンビニのパンとコーヒーを適当に食べて出かけていました。</p>

<h4 id="0845-出発">08:45 出発</h4>

<p><img src="/assets/aacd5f5cacd1/1*HIa6B4yuh-MjFWMeBs97IQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*HIa6B4yuh-MjFWMeBs97IQ.jpeg" /></p>

<p>朝8時45分、ホテルを出て人通りのない商店街を通り駅へ向かう。</p>

<h4 id="0855-バスで書写山円教寺へ向かう">08:55 バスで書写山円教寺へ向かう</h4>

<p><img src="/assets/aacd5f5cacd1/1*Z3_zOdcbly3jEyXyN8RKWA.webp" alt="" loading="lazy" decoding="async" width="918" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MTgiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Z3_zOdcbly3jEyXyN8RKWA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*3KNztIIzy_Yw85kEm5ai-Q.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*3KNztIIzy_Yw85kEm5ai-Q.jpeg" /></p>

<p>姫路駅にはいくつかのホームがあり、Google Mapにはどのホームかや何番のバスに乗るかは書かれていません。現地の案内表示を確認し、10番ホームから10番の姫路駅北〜書写山ロープウェイのバスに乗ります。</p>

<blockquote>
  <p><em>書寫山圓教寺は映画『ラストサムライ』のロケ地です：</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*ElCz1QpeR3XaKMbYyPvuPQ.webp" alt="&lt;https://visit-himeji.com/zh-hant/trip-ideas/featured-in-the-last-samurai-shoshazan-engyoji-temple-in-himeji/&gt;" loading="lazy" decoding="async" width="1069" height="973" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDY5IiBoZWlnaHQ9Ijk3MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ElCz1QpeR3XaKMbYyPvuPQ.png" /></p>

<p><a href="https://visit-himeji.com/zh-hant/trip-ideas/featured-in-the-last-samurai-shoshazan-engyoji-temple-in-himeji/" target="_blank">https://visit-himeji.com/zh-hant/trip-ideas/featured-in-the-last-samurai-shoshazan-engyoji-temple-in-himeji/</a></p>

<h4 id="0920-書写山ロープウェイ乗り場に到着">~=09:20 書写山ロープウェイ乗り場に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*a7E1GJ36evNeg3HIpTajiA.webp" alt="" loading="lazy" decoding="async" width="1395" height="1049" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzk1IiBoZWlnaHQ9IjEwNDkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*a7E1GJ36evNeg3HIpTajiA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*deyU47Fxzh-iOMa3Cm6RMg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*deyU47Fxzh-iOMa3Cm6RMg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*d-BdwUp1HRFSSl_Zu16cDQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*d-BdwUp1HRFSSl_Zu16cDQ.jpeg" /></p>

<p>降車後すぐにロープウェイ乗り場があり、自動券売機で往復券を購入したら列に並んでロープウェイを待てます。（15分間隔）</p>

<p><img src="/assets/aacd5f5cacd1/1*Q96ZZxOE04V57QXJcsL2iA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Q96ZZxOE04V57QXJcsL2iA.jpeg" /></p>

<p>書寫山では11月15日から17日まで夜間特別開放があり、夜20時まで開いています。ロープウェイの運行時間も20時30分まで延長されます。</p>

<h4 id="0930-ロープウェイに乗って山へ上る">09:30 ロープウェイに乗って山へ上る</h4>

<p><img src="/assets/aacd5f5cacd1/1*-t6iFYeu1txyQ6-B9pZdCQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*-t6iFYeu1txyQ6-B9pZdCQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*2MnYBWj9005tN57I3IRrXQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*2MnYBWj9005tN57I3IRrXQ.jpeg" /></p>

<h4 id="0935-書写山円教寺入口に到着">09:35 書写山円教寺入口に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*4AYY1gP1Kdb589JwBHaFuw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1010" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*4AYY1gP1Kdb589JwBHaFuw.png" /></p>

<p>入場券が必要で、その時はよく確認せずに<strong>一般の入山志納金だけを購入し、往復のシャトルバスには乗れず、徒歩で山を登る必要がありました</strong>。⚠️⚠️⚠️</p>

<blockquote>
  <p><em>乗車時間：約5分</em></p>
</blockquote>

<blockquote>
  <p><em>登山：約20分（1KM）</em></p>
</blockquote>

<blockquote>
  <p><strong><em>もしもう一度選べるなら、500円多く払って時間と体力を節約します。</em></strong></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*p4QIb3vPtJivhpdoDQ6GAQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*p4QIb3vPtJivhpdoDQ6GAQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*7e4WBDn1nRnJYdz5B_hYOA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*7e4WBDn1nRnJYdz5B_hYOA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ewt3SGQwn6WyhRV7Am0_MA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ewt3SGQwn6WyhRV7Am0_MA.jpeg" /></p>

<p>でも、朝早くて体力も気力もまだ十分あったので、緩やかな坂道を歩きながら紅葉を楽しみつつ山を登りました。</p>

<p><img src="/assets/aacd5f5cacd1/1*AS55vHl96nZYuwqjRa93ZA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*AS55vHl96nZYuwqjRa93ZA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*T8xwRPwgXPqr5nZ5LXUq2w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*T8xwRPwgXPqr5nZ5LXUq2w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*W-yWWLLv0UJlQ2QU10Q3Vg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*W-yWWLLv0UJlQ2QU10Q3Vg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*fcCW8202ZiA2OcPgUm-gKw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*fcCW8202ZiA2OcPgUm-gKw.jpeg" /></p>

<p>仁王門を通り過ぎてから約400メートルです。</p>

<h4 id="0955-摩尼殿に到着">09:55 摩尼殿に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*ceS4fQCizXrx1avWg9Y3yw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ceS4fQCizXrx1avWg9Y3yw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*80TxXA5vgZrLaPnSGHQVlQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*80TxXA5vgZrLaPnSGHQVlQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*6m7mDkJHyCYezj5AlTKznA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*6m7mDkJHyCYezj5AlTKznA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*fLzPG1W3E1eJ4_pEYPKepQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*fLzPG1W3E1eJ4_pEYPKepQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*AxTqVqv_JomxzIlBE_HbSA.webp" alt="" loading="lazy" decoding="async" width="965" height="1232" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjUiIGhlaWdodD0iMTIzMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*AxTqVqv_JomxzIlBE_HbSA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*5nc-fnNgZHhIwlJhTcYKjg.webp" alt="" loading="lazy" decoding="async" width="1400" height="899" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijg5OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*5nc-fnNgZHhIwlJhTcYKjg.png" /></p>

<p>書寫山圓教寺は広大で、全部歩くには少なくとも2時間はかかると思います。</p>

<p><img src="/assets/aacd5f5cacd1/1*U4wMNwdurbeaNEOqUKkC9Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="529" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjUyOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*U4wMNwdurbeaNEOqUKkC9Q.png" /></p>

<p>私は摩尼殿と大講堂だけ参拝して、すぐに下山しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*h70I3V6EU2UIea8JaVs_jw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*h70I3V6EU2UIea8JaVs_jw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*cQEiVSO01SrHGYuhQb8Y6A.webp" alt="" loading="lazy" decoding="async" width="946" height="1234" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NDYiIGhlaWdodD0iMTIzNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*cQEiVSO01SrHGYuhQb8Y6A.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*IyDpkfR-0QmrIiNwGg0aJA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*IyDpkfR-0QmrIiNwGg0aJA.jpeg" /></p>

<p>摩尼殿は靴を脱いで参拝できますし、ここから紅葉を見下ろすこともできます。</p>

<p><img src="/assets/aacd5f5cacd1/1*BbDp9dGeoep-40MgJeDiOQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*BbDp9dGeoep-40MgJeDiOQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*fImTadRZFNlut58qayxvhQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*fImTadRZFNlut58qayxvhQ.jpeg" /></p>

<p>とても静かで落ち着いていますが、今年の紅葉は遅く、赤くなっている木はまばらです。</p>

<p><img src="/assets/aacd5f5cacd1/1*mVNbxhCrjF5jWx5MXgRNWA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*mVNbxhCrjF5jWx5MXgRNWA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*9j_zrDZmNITjHHmA56PmCQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*9j_zrDZmNITjHHmA56PmCQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*mbYDfRbjjG6Z5_w8mI--EQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*mbYDfRbjjG6Z5_w8mI--EQ.jpeg" /></p>

<p>殿後小路から前方に進み、大講堂へ向かいます。</p>

<p><img src="/assets/aacd5f5cacd1/1*hsCWaBEKnGp5QMX_YaF4Gw.webp" alt="" loading="lazy" decoding="async" width="1200" height="870" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg3MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*hsCWaBEKnGp5QMX_YaF4Gw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*0yUCPUF_oEy4manAS8kJ0A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*0yUCPUF_oEy4manAS8kJ0A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*gjTjoLDLZC6EeAP3Gcnbdw.webp" alt="" loading="lazy" decoding="async" width="960" height="1244" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjAiIGhlaWdodD0iMTI0NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*gjTjoLDLZC6EeAP3Gcnbdw.png" /></p>

<p>大講堂には<a href="https://x.com/kugikumo" target="_blank">圓教寺 x 隈研吾</a>のインスタレーションアートがあり、12月1日まで展示されています。</p>

<p><img src="/assets/aacd5f5cacd1/1*4m561KwGCbbgXnrrYERkJw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4m561KwGCbbgXnrrYERkJw.jpeg" /></p>

<p>大講堂のそばの紅葉がとても赤い。</p>

<blockquote>
  <p><em>大講堂に着いたとき、ちょうどお経を唱えていて、靴を脱いで中に入り参拝できました。日本の僧侶のお経の唱え方は台湾と少し違い、経文を全部広げて唱え、最後に閉じてパタンと叩きます。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*V_0ogPmKoPiQ9-nuUfxvlw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*V_0ogPmKoPiQ9-nuUfxvlw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*NKB_Hzykps-3rC3HHrxHIg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*NKB_Hzykps-3rC3HHrxHIg.jpeg" /></p>

<p>隣の食堂も見学でき、多くの歴史的な資料が展示されています。</p>

<p>すべての建物は史跡（1282年建造）であり、歩くと歴史を感じることができます。全体の建物はよく保存・管理されています。</p>

<p><img src="/assets/aacd5f5cacd1/1*T4ybcdOD3Fr9qJPRvKyjvA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*T4ybcdOD3Fr9qJPRvKyjvA.jpeg" /></p>

<p>食堂の2階から大講堂を見たところ。</p>

<p><img src="/assets/aacd5f5cacd1/1*kwc7TD6kOkAMUEGCyQZyHw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*kwc7TD6kOkAMUEGCyQZyHw.jpeg" /></p>

<p>大講堂を見学した後、摩尼殿に戻り、摩尼殿の外にあるお店で焼きたてのあんこ餅を買ってエネルギー補給をしました。（焼きたては美味しくて、皮がパリッとしています）</p>

<p><img src="/assets/aacd5f5cacd1/1*3vuyM_hvr2vqmMigtjrJfQ.webp" alt="安全に帰宅してください。" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*3vuyM_hvr2vqmMigtjrJfQ.jpeg" /></p>

<p>お気をつけてお帰りください。</p>

<p>食事の後、さらに20分歩いて下山し、志納所入口に戻りました。</p>

<h4 id="1055-ロープウェイで下山">~=10:55 ロープウェイで下山</h4>

<p><img src="/assets/aacd5f5cacd1/1*HYi218ukiOp87of9sIPW7g.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*HYi218ukiOp87of9sIPW7g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*MxZa66WDA3XJLESJ6bTAHA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*MxZa66WDA3XJLESJ6bTAHA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*CPsPU2ed-0Dr7Xk1yyszAw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*CPsPU2ed-0Dr7Xk1yyszAw.jpeg" /></p>

<h4 id="1110-姫路市街地へ戻る">11:10 姫路市街地へ戻る</h4>

<p><img src="/assets/aacd5f5cacd1/1*--Rj51jGDSdIKsruPXX5OQ.webp" alt="" loading="lazy" decoding="async" width="938" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MzgiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*--Rj51jGDSdIKsruPXX5OQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*mLKgafi4UWM-lqsxIxnTHg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*mLKgafi4UWM-lqsxIxnTHg.jpeg" /></p>

<p>下山して戻るときのバス停は、だいたい11:05で、11:10のバスに乗って姫路市街へ戻ります。</p>

<h4 id="-1135-姫路城に到着">~= 11:35 姫路城に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*rVlB-YbFKOoCB_4vUzk50w.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*rVlB-YbFKOoCB_4vUzk50w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*kxFG8jVc9-4cfH5uTVpbsQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*kxFG8jVc9-4cfH5uTVpbsQ.jpeg" /></p>

<p>バスを降りて少し歩くと姫路城の遊覧船がありますが、天気が曇っていて雨が降りそうだったので行きませんでした。</p>

<p><img src="/assets/aacd5f5cacd1/1*ReisZ-PRti3sK13ozeceDA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*ReisZ-PRti3sK13ozeceDA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*OwoTR1-C35HhJiv-rq8o2w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*OwoTR1-C35HhJiv-rq8o2w.jpeg" /></p>

<p>姫路城に入ると、入口のこの橋の景色は写真撮影にぴったりです！</p>

<p><img src="/assets/aacd5f5cacd1/1*KmgaWgD9UXFA3R6UGw8QoQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*KmgaWgD9UXFA3R6UGw8QoQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*NISOgxwwrowWgi9jHz_qWw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*NISOgxwwrowWgi9jHz_qWw.jpeg" /></p>

<p>姫路城前の三の丸広場はとても広く、ここから城の入口までさらに5分歩かなければなりません。</p>

<p><img src="/assets/aacd5f5cacd1/1*TczWjw__6r_H15vgUwkcUQ.webp" alt="" loading="lazy" decoding="async" width="726" height="660" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MjYiIGhlaWdodD0iNjYwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*TczWjw__6r_H15vgUwkcUQ.png" /></p>

<p>まず、昨日通りすがりの人に教えてもらった姫路城の撮影スポットに行ってみようと思いました。撮影スポットは入城口とは反対側の右手にある「姫路市動物園」の中にあります。</p>

<p><img src="/assets/aacd5f5cacd1/1*NAGnOqG4plLpo1AVEtwCgg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*NAGnOqG4plLpo1AVEtwCgg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*UzJF2eGGGmIhgK_a3xANAA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*UzJF2eGGGmIhgK_a3xANAA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Ms3Z4aqqUSa2RWA35dGc1g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Ms3Z4aqqUSa2RWA35dGc1g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*GmIPAY57WWuEBRXl6tmcBw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*GmIPAY57WWuEBRXl6tmcBw.jpeg" /></p>

<p>宣伝を見ると右手にカピバラがいるが、寒すぎて出てこなかった可能性がある。中に入って直進し、橋を渡って観覧車が見えたら右折する。その後ろにある空き地が撮影スポットだ。</p>

<p><img src="/assets/aacd5f5cacd1/1*Rupw705abK9nx8m8x0MPdw.webp" alt="&lt;https://youtube.com/shorts/XDquPOanhpQ&gt;" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*Rupw705abK9nx8m8x0MPdw.jpeg" /></p>

<p><a href="https://youtube.com/shorts/XDquPOanhpQ" target="_blank">https://youtube.com/shorts/XDquPOanhpQ</a></p>

<p>この撮影スポットの構図はとても良いですが、桜や紅葉がなくて残念です。</p>

<p><img src="/assets/aacd5f5cacd1/1*84kPNVhjXpUqyGMCbSgE1Q.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*84kPNVhjXpUqyGMCbSgE1Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*JPyc8SBiGKtcrh9r31l3iQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*JPyc8SBiGKtcrh9r31l3iQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*xUkRrlHFLbKJWKjnVAw59A.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*xUkRrlHFLbKJWKjnVAw59A.jpeg" /></p>

<blockquote>
  <p><em>撮影後、動物園を少し回りましたが、施設は非常に古く（遊具は別料金）、動物のスペースも狭く、<strong>多くの動物が憂鬱そうで、常同行動が見られ、見ていられない</strong> 状態でした。少し見てすぐに離れました。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*Ua__vVJVs-uFK2f4yD6erA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*Ua__vVJVs-uFK2f4yD6erA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*pNyzUtrYYyKahNitfuhxBg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*pNyzUtrYYyKahNitfuhxBg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*KEQvJI90xEVXc4r4GQ0wew.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*KEQvJI90xEVXc4r4GQ0wew.jpeg" /></p>

<p>姫路城の撮影を終えた後、左側の城の入口に戻り、城内を見学しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*NDwQbWnS0PRC8k90t6MIcw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*NDwQbWnS0PRC8k90t6MIcw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*h0xLPH3EGTMSljU26o5GLw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*h0xLPH3EGTMSljU26o5GLw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*wVG-5blJurZ0maq8rx5IDg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*wVG-5blJurZ0maq8rx5IDg.jpeg" /></p>

<p>チケットを購入したら、見学ルートに沿ってそのまま城内へ進みます。</p>

<p><img src="/assets/aacd5f5cacd1/1*j-yJn4Drf_XR8nZn9aO19w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*j-yJn4Drf_XR8nZn9aO19w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*6NcZZitF85yrZIt8J6kSmw.webp" alt="" loading="lazy" decoding="async" width="928" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MjgiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*6NcZZitF85yrZIt8J6kSmw.png" /></p>

<p>室内に入る際も靴を脱ぎ、靴を入れるためのビニール袋が配られます。</p>

<p><img src="/assets/aacd5f5cacd1/1*LD55vnyY6e_RUQpxAhenDg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*LD55vnyY6e_RUQpxAhenDg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*dRqPqCQhSezJ5wsttSJeVg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*dRqPqCQhSezJ5wsttSJeVg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*zl-BV1uAW_u3qxG-KR4wLQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*zl-BV1uAW_u3qxG-KR4wLQ.jpeg" /></p>

<p>二階から姫路駅を振り返ると、全部で六階あり、上に行くほど狭くなり、階段も急になっていきます。階段に並んで登る必要があります。</p>

<blockquote>
  <p><em>この時すでに昼の12:30に近く、お腹も空いていて、さらに今日はモバイルバッテリーを忘れてきたため、スマホのバッテリーもほぼ切れかけていました。加えて行列も多かったので、これ以上登らずに二階で引き返して城を出ました。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*yjWyIFXF4Adh-MEwmBLpsA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*yjWyIFXF4Adh-MEwmBLpsA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*zcaGTdjsKLn3hEBR92zb4g.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*zcaGTdjsKLn3hEBR92zb4g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Zohjzd5XZTXDuf-IkRpI8Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*Zohjzd5XZTXDuf-IkRpI8Q.jpeg" /></p>

<p>城を出てから三の丸広場まで歩き、そこから外へ出ました。</p>

<p><img src="/assets/aacd5f5cacd1/1*Q-BpgNDNoWH4qo3mxZFA5A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Q-BpgNDNoWH4qo3mxZFA5A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*JmXBE3gSYq898CG_1y-rLA.webp" alt="串焼き神戸牛" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*JmXBE3gSYq898CG_1y-rLA.jpeg" /></p>

<p><a href="https://maps.app.goo.gl/3ANcmi6uR1wnDgqYA" target="_blank">串焼き神戸牛</a></p>

<p>姫路城の外の商店街で神戸牛を扱う店を見つけ、神戸牛丼と串焼きをテイクアウトしてホテルで休憩しながら充電しました。</p>

<h4 id="1320-ホテルに戻って休憩">13:20 ホテルに戻って休憩</h4>

<p>天候不良＋朝の登山＋スマホのバッテリー切れ＝ホテルに戻って休憩。</p>

<p><img src="/assets/aacd5f5cacd1/1*Sp_2bL6TiDs-FTIT1hf4cg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Sp_2bL6TiDs-FTIT1hf4cg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*0BxN4BJO9GZ3jCHQr7_qpg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*0BxN4BJO9GZ3jCHQr7_qpg.jpeg" /></p>

<p>量は少し少なめですが、ここの神戸牛の味はなかなか良いです。</p>

<h4 id="1530-姫路駅周辺でショッピング">15:30 姫路駅周辺でショッピング</h4>

<p>だいたい15:30まで休んでから、再び出かけました。</p>

<p><img src="/assets/aacd5f5cacd1/1*VoC5czZ4ep3Pej07BaIl8g.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*VoC5czZ4ep3Pej07BaIl8g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*bU2RJeIL3HZ-eIE5aGQ0-A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*bU2RJeIL3HZ-eIE5aGQ0-A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*1yvJy0uUoWXpna40MC5ZTg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*1yvJy0uUoWXpna40MC5ZTg.jpeg" /></p>

<p>姫路駅周辺は意外とあまり見どころがなく、駅にあるPioleと山陽電車の百貨店、周囲の商店街だけです。ドン・キホーテやマクドナルドはなく、ローソンも1軒だけ、ドラッグストアは松本清が1軒だけです。</p>

<p><img src="/assets/aacd5f5cacd1/1*EtwTImtOX4SlPrRo6CKBYg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*EtwTImtOX4SlPrRo6CKBYg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*H_cAfQPJP8QXU_7MPgzYyA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*H_cAfQPJP8QXU_7MPgzYyA.jpeg" /></p>

<p>Pioleの3階にあるKiddy Landにはいくつかのジイカワがあり、ここはあまり人がいなくて並ばずに済みました。3匹の赤ちゃんを連れて帰りましたが、ウサチはパジャマバージョンが買えませんでしたQQ。</p>

<p><img src="/assets/aacd5f5cacd1/1*kG_MA7MnFH9QHo2YPKbofw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*kG_MA7MnFH9QHo2YPKbofw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*DZIjEJdNFvBHGIdphvJ8Kw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*DZIjEJdNFvBHGIdphvJ8Kw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*AGyjVuNTXv_gO9DfdSKAIg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*AGyjVuNTXv_gO9DfdSKAIg.jpeg" /></p>

<p>商店街をぶらぶらして、ガチャガチャを探す旅。</p>

<p><img src="/assets/aacd5f5cacd1/1*61f9uD9NUYRW1QumaFpNLA.webp" alt="" loading="lazy" decoding="async" width="1400" height="961" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk2MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*61f9uD9NUYRW1QumaFpNLA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*wxoORyKqaWXDmUt9lk9vRg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1016" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*wxoORyKqaWXDmUt9lk9vRg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YtH0na_odN_spz7_I1o6cQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YtH0na_odN_spz7_I1o6cQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*yNe-JTCDJuloVlg7xdtGwA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*yNe-JTCDJuloVlg7xdtGwA.jpeg" /></p>

<p>あまり見るところはないと言いましたが、少なくともガチャガチャ店やアニメイトはありました。</p>

<p><img src="/assets/aacd5f5cacd1/1*o5h-XaDa6kZ6kjXjPAq7Rw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*o5h-XaDa6kZ6kjXjPAq7Rw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*9u7HGC1YdSWWcS_1_iqMzw.webp" alt="" loading="lazy" decoding="async" width="695" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2OTUiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*9u7HGC1YdSWWcS_1_iqMzw.png" /></p>

<p>夕方近くから大雨が降り始めましたが、今日は特に予定がなかったので助かりました。</p>

<h4 id="1800-夕食を食べる">~=18:00 夕食を食べる</h4>

<p><img src="/assets/aacd5f5cacd1/1*UJqc0DWngnbESTHo_PybYw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*UJqc0DWngnbESTHo_PybYw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*IJ8XIPnSJdaAx-6OkmCoJg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*IJ8XIPnSJdaAx-6OkmCoJg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*66Zxcn9rbOdkL3GqjV_cNA.webp" alt="おだしとワインとお料理と。motto" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*66Zxcn9rbOdkL3GqjV_cNA.jpeg" /></p>

<p><a href="https://maps.app.goo.gl/arsJs8CYEW3kAdg46" target="_blank">おだしとワインとお料理と。motto</a></p>

<p>商店街で適当に神戸牛のある店を見つけて夕食にしました。</p>

<p><img src="/assets/aacd5f5cacd1/1*5Cc0K6Xd5p0FMJbxhB4gOg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*5Cc0K6Xd5p0FMJbxhB4gOg.jpeg" /></p>

<p>こちらの特徴は、前菜に招き猫のデザートがあり、甘すぎずなかなか良い点です。</p>

<p><img src="/assets/aacd5f5cacd1/1*1b3oeJs9c2rjOL-TaleOQg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1b3oeJs9c2rjOL-TaleOQg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*6ijkG1uNzojnZlIkRc2fMA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*6ijkG1uNzojnZlIkRc2fMA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*i_EvfGqTY-fQQdXlK7aBjA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*i_EvfGqTY-fQQdXlK7aBjA.jpeg" /></p>

<p>神戸牛ステーキとお茶漬け、生ビールを注文しました。</p>

<p>ここの神戸牛ステーキは普通で、あまり柔らかくなく神戸牛の味もあまり感じられませんでした。お茶漬けは結構美味しかったです。</p>

<p><img src="/assets/aacd5f5cacd1/1*Z0oLUni88-W6TPpVm2gF6g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Z0oLUni88-W6TPpVm2gF6g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*q_ek8sUX3nM5xCBTPkXa6Q.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*q_ek8sUX3nM5xCBTPkXa6Q.jpeg" /></p>

<p>お腹がいっぱいになった後、雨上がりの姫路をぶらぶら散歩。</p>

<h4 id="2000-ホテルに戻って休憩日台戦を見る">~=20:00 ホテルに戻って休憩＆日台戦を見る</h4>

<p><img src="/assets/aacd5f5cacd1/1*j17lqXN-p1caPqDaC6z-rA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*j17lqXN-p1caPqDaC6z-rA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*oBZH4_-Pb7difuUCdwvSBw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*oBZH4_-Pb7difuUCdwvSBw.jpeg" /></p>

<p>日本の視点で、実況内容は全く理解できませんが、日本の中継情報はとても充実していて、左側には野球の知識補足があり、右側には詳細な球種分析があります。</p>

<p><img src="/assets/aacd5f5cacd1/1*4wJ-WWxbgYAeGgcf-KPtyQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4wJ-WWxbgYAeGgcf-KPtyQ.jpeg" /></p>

<p>最後の勝者は日本でした。</p>

<blockquote>
  <p><em>おやすみ、姫路。</em></p>
</blockquote>

<h3 id="6日目1117日曜日-大阪神戸">6日目（11/17日曜日） 大阪、神戸</h3>

<p>本当は鳴門の渦潮や明石海峡大橋に行く予定でしたが、天候が悪かったため、大阪と神戸でショッピングに変更しました。</p>

<h4 id="-0845-新幹線自由席で新大阪へ向かう">~= 08:45 新幹線自由席で新大阪へ向かう</h4>

<p><img src="/assets/aacd5f5cacd1/1*T5blo2Kdt0KsYaItd6H5dA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*T5blo2Kdt0KsYaItd6H5dA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*RvSje4c8thVxGXJpBZwnTA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*RvSje4c8thVxGXJpBZwnTA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*gGkwpzey7E9tlg0gbbV35g.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*gGkwpzey7E9tlg0gbbV35g.jpeg" /></p>

<p>新幹線で新大阪まで（25分）、そこから御堂筋線に乗り換えて大阪へ行く時間は、普通電車で直接大阪に行くのとほぼ同じです。新幹線は本数が多いため、快適で充電もできる新幹線を選びました。</p>

<h4 id="917-新大阪に到着">9:17 新大阪に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*apUd_VYqJJ_mM_Kr_R3YnQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="765" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc2NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*apUd_VYqJJ_mM_Kr_R3YnQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*6ptZt3XbRNnIK1Ph62j9eg.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*6ptZt3XbRNnIK1Ph62j9eg.jpeg" /></p>

<p>新大阪に到着した後、御堂筋線まで少し歩く必要があります。</p>

<p>まずは<a href="/posts/z-度旅行遊記/京阪神自由行-8日間の京都-大阪-神戸旅行完全ガイド-食事-宿泊-交通情報を網羅-76d66c2e34af/">去年の京阪神旅行</a>で行けなかった難波八阪神社へ行きます。</p>

<p><img src="/assets/aacd5f5cacd1/1*vWqBuGY0nf4NQY1pw5Pb7w.webp" alt="" loading="lazy" decoding="async" width="882" height="1095" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4ODIiIGhlaWdodD0iMTA5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*vWqBuGY0nf4NQY1pw5Pb7w.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*uCKGMuqTmPVL61gvJU_AKg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*uCKGMuqTmPVL61gvJU_AKg.jpeg" /></p>

<p>難波駅で降りて少し歩くと、ある路地の中に神社があります。</p>

<blockquote>
  <p><em>大阪でも顔認証による改札通過のテストが行われていることに気づきました。</em></p>
</blockquote>

<h4 id="950-難波八阪神社に到着">~=9:50 難波八阪神社に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*DCyi2vXA6WzEvhxJ9Qx6Uw.webp" alt="" loading="lazy" decoding="async" width="866" height="1107" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjYiIGhlaWdodD0iMTEwNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*DCyi2vXA6WzEvhxJ9Qx6Uw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*qu1yc41lJWfbKvt2iiI8Og.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*qu1yc41lJWfbKvt2iiI8Og.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*eENL5QrW5I0g_Bb3Iqlc6Q.webp" alt="" loading="lazy" decoding="async" width="1200" height="873" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg3MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*eENL5QrW5I0g_Bb3Iqlc6Q.png" /></p>

<p>神社は大きくなく、観光客が多いので、立ち寄って写真を数枚撮っただけで離れました。</p>

<p><img src="/assets/aacd5f5cacd1/1*Ms6lilqCGKSJEQY-2Ad_NQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Ms6lilqCGKSJEQY-2Ad_NQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*1YnEjMoc8KV-OaV08XrMcA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1YnEjMoc8KV-OaV08XrMcA.jpeg" /></p>

<p>離れた後、次の駅「大国町」まで歩き、一駅乗って「動物園前」で下車し、通天閣へ向かいます。</p>

<p><img src="/assets/aacd5f5cacd1/1*bxBxGhqonhPE-kNU7jl5DA.webp" alt="" loading="lazy" decoding="async" width="877" height="1071" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzciIGhlaWdodD0iMTA3MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*bxBxGhqonhPE-kNU7jl5DA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*_ZGMWno1bnS5VIsevjVuGw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_ZGMWno1bnS5VIsevjVuGw.jpeg" /></p>

<p>改札を出て地下道や商店街を通り抜けて進むと、通天閣が見えます。</p>

<blockquote>
  <p><em>ここは治安があまり良くない感じで、駅を出て地下道を通ると多くのホームレスがいて、ホームレス同士が大声で喧嘩していて少し怖かった。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*WOzCL0xA6hirl6Ru3iYxlg.webp" alt="" loading="lazy" decoding="async" width="859" height="1130" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NTkiIGhlaWdodD0iMTEzMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*WOzCL0xA6hirl6Ru3iYxlg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*xWz0KkdvI5042L31ritmjw.webp" alt="" loading="lazy" decoding="async" width="1200" height="852" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*xWz0KkdvI5042L31ritmjw.png" /></p>

<p>商店街の路地は狭く、左右に飲食店が並んでいます。いくつかは行列ができる人気店のようで、多くの人で賑わっていました。</p>

<p><img src="/assets/aacd5f5cacd1/1*-cCMXQtTVn7ExtRxRLyOcA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*-cCMXQtTVn7ExtRxRLyOcA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*89McCOa7Itm_L97WibLASw.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*89McCOa7Itm_L97WibLASw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*GiVI9kQjjJLKp5E0BYq__Q.webp" alt="" loading="lazy" decoding="async" width="875" height="1093" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzUiIGhlaWdodD0iMTA5MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*GiVI9kQjjJLKp5E0BYq__Q.png" /></p>

<p>約10時30分に通天閣の下に到着しましたが、登るための長い行列ができていたので、私はすぐに諦めました。</p>

<p><img src="/assets/aacd5f5cacd1/1*oRVH7x_G3Ga19FD04YQCIg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*oRVH7x_G3Ga19FD04YQCIg.jpeg" /></p>

<p>地下鉄の駅まで歩いて大阪に戻る。</p>

<h4 id="1100-大阪梅田に戻る">~=11:00 大阪梅田に戻る</h4>

<p><img src="/assets/aacd5f5cacd1/1*A97lYcYLqPya_YJp3UFQxw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*A97lYcYLqPya_YJp3UFQxw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*kbWzjvQnQicbyGhGx7qLAw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*kbWzjvQnQicbyGhGx7qLAw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*i-1TYGeHu_AxlzRaluBkGw.webp" alt="" loading="lazy" decoding="async" width="874" height="1099" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzQiIGhlaWdodD0iMTA5OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*i-1TYGeHu_AxlzRaluBkGw.png" /></p>

<p>改札を出てまずLINKSデパートへ。5階から直接ヨドバシのガチャガチャおもちゃコーナーに行けます。</p>

<p><img src="/assets/aacd5f5cacd1/1*LHUFlm9UQQto7rkwZ4oJ6A.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*LHUFlm9UQQto7rkwZ4oJ6A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*4BeiVIybWx9ixjgSA3Kp6A.webp" alt="" loading="lazy" decoding="async" width="1400" height="977" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk3NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4BeiVIybWx9ixjgSA3Kp6A.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*RafKwlM7JvNBLvYwtTFhrA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*RafKwlM7JvNBLvYwtTFhrA.jpeg" /></p>

<p>LINKSを見た後、大阪駅とその上の時空の広場を通り抜けて、大阪大丸百貨店に直行しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*a02vHVVx_CBehnuTqyh9jA.webp" alt="" loading="lazy" decoding="async" width="1200" height="849" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*a02vHVVx_CBehnuTqyh9jA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Xa_Xd-BwWMKuukRyd5Tz8w.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Xa_Xd-BwWMKuukRyd5Tz8w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*iCYhY01vtTyAvBSsh3NWuw.webp" alt="" loading="lazy" decoding="async" width="1200" height="843" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*iCYhY01vtTyAvBSsh3NWuw.png" /></p>

<p>13階にはポケモンセンター、大阪任天堂、CAPCOMがあります…</p>

<p><img src="/assets/aacd5f5cacd1/1*EJivBHlcWiG1tgWQoVQWQQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*EJivBHlcWiG1tgWQoVQWQQ.jpeg" /></p>

<p>ゼルダのグッズをちょっと見てみましたが、<a href="/posts/z-度旅行遊記/京阪神自由行-8日間の京都-大阪-神戸旅行完全ガイド-食事-宿泊-交通情報を網羅-76d66c2e34af/">前回はもうたくさん買いました</a>、今回は何も買わずにそのまま帰りました。</p>

<p><img src="/assets/aacd5f5cacd1/1*1H-S0fCwZQFmXJNLTMEISQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*1H-S0fCwZQFmXJNLTMEISQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YxL275thElHiiaMctikMGg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YxL275thElHiiaMctikMGg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*pNCyg_53IysVfZa5ndJLXg.webp" alt="" loading="lazy" decoding="async" width="1200" height="845" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg0NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*pNCyg_53IysVfZa5ndJLXg.png" /></p>

<p>阪神タイガース関連ショップの前を通りかかりました。</p>

<p>Shake Shackを食べに行く準備をしています。7月にバンコクで食べて、<a href="https://medium.com/ztravel/%E9%81%8A%E8%A8%98-2024-%E6%B3%B0%E5%9C%8B%E6%9B%BC%E8%B0%B7-bangkok-5-%E6%97%A5%E8%87%AA%E7%94%B1%E8%A1%8C-b7e7c0938985?source=collection_home---4------0-----------------------" target="_blank">まだ満足していません</a>；大阪で再び味わいます。</p>

<h4 id="1200-シェイクシャック">~=12:00 シェイクシャック</h4>

<p><img src="/assets/aacd5f5cacd1/1*EV2jpsFyxgjE9lVIg3isgw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*EV2jpsFyxgjE9lVIg3isgw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*w3Nl5TcRSrFT-9ugnIpuug.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*w3Nl5TcRSrFT-9ugnIpuug.jpeg" /></p>

<p><a href="https://maps.app.goo.gl/LfNFo7TJK7gEZrcN6" target="_blank">Shake Shack 阪神梅田店</a> は阪神タイガースショップの隣にあります。</p>

<p><img src="/assets/aacd5f5cacd1/1*GZ_3ywx9RZuH5BuTp0bseQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*GZ_3ywx9RZuH5BuTp0bseQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*KdW0FlYYw-Iit-2uYclbLQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*KdW0FlYYw-Iit-2uYclbLQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*chnnVelVCqU-6IsNNWHEGg.webp" alt="" loading="lazy" decoding="async" width="873" height="1136" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzMiIGhlaWdodD0iMTEzNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*chnnVelVCqU-6IsNNWHEGg.png" /></p>

<p>セルフオーダーで、今回はアボカドベーコンチキンバーガーとシェイクを注文しました。こちらのお店は広くて席も多いです。</p>

<p><img src="/assets/aacd5f5cacd1/1*Hqk1yAuVB8DpddJFgHrPZg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Hqk1yAuVB8DpddJFgHrPZg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*-Ud0FELy464hSGqc-6i2mg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*-Ud0FELy464hSGqc-6i2mg.jpeg" /></p>

<h4 id="大阪駅">大阪駅</h4>

<p><img src="/assets/aacd5f5cacd1/1*cBx2n43-tFXz7zHHk9YIBQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*cBx2n43-tFXz7zHHk9YIBQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*fhj864wdmrcC9LyNv0Xl6A.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*fhj864wdmrcC9LyNv0Xl6A.jpeg" /></p>

<p>食事の後、大阪駅周辺をぶらぶらしながら、大阪のKiddy Landでジイカワを探してみようと思いました。</p>

<p><img src="/assets/aacd5f5cacd1/1*lKUQzWMeXVljaUZvdyKy9Q.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*lKUQzWMeXVljaUZvdyKy9Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*oyvLMv7OPW7GbnylhM072g.webp" alt="" loading="lazy" decoding="async" width="1200" height="856" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*oyvLMv7OPW7GbnylhM072g.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*qyNQwZ0U6ZWvoyVpBq69yA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*qyNQwZ0U6ZWvoyVpBq69yA.jpeg" /></p>

<p>大阪の地下街で迷ってしまい、長い時間かけてようやく阪急三番街を見つけました。そこから地下連絡通路を通って南館から北館へ移動し、グルメ街に到着しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*EJF9zT0iOWMNlMddrLdCkQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*EJF9zT0iOWMNlMddrLdCkQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*7vqSVT1kVyDJQMFtlcOy_w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*7vqSVT1kVyDJQMFtlcOy_w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*BYv-IJr_v2YuYmD_-FLjoA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*BYv-IJr_v2YuYmD_-FLjoA.jpeg" /></p>

<p>吉井川は別の場所に独立したブースを設けています。</p>

<h4 id="1300-キディランド大阪-チイカワ">13:00 キディランド大阪 チイカワ</h4>

<p><img src="/assets/aacd5f5cacd1/1*Cct5wKtjkqkFmVhrZSEraw.webp" alt="" loading="lazy" decoding="async" width="1200" height="865" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Cct5wKtjkqkFmVhrZSEraw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*xvhRITM1s26Q9sgxLP5ZWg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*xvhRITM1s26Q9sgxLP5ZWg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*r4v-nQd9yCftkhFxmVafyA.webp" alt="" loading="lazy" decoding="async" width="880" height="1095" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4ODAiIGhlaWdodD0iMTA5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*r4v-nQd9yCftkhFxmVafyA.png" /></p>

<p>並んでいる人がかなり多く、ざっと見積もって少なくとも40分以上は待つ必要があります。</p>

<blockquote>
  <p><strong><em>もちろん、私は並んで待つ時間は使いませんでした。</em></strong></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*uJHEegOR7Zr8Vlp-DqbYCA.webp" alt="" loading="lazy" decoding="async" width="1163" height="636" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTYzIiBoZWlnaHQ9IjYzNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*uJHEegOR7Zr8Vlp-DqbYCA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*QYlEBbbuFij9v2_60PQXeg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*QYlEBbbuFij9v2_60PQXeg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*E3rZ-ET_Z8qEO6Eo3QIyeA.webp" alt="" loading="lazy" decoding="async" width="868" height="1102" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjgiIGhlaWdodD0iMTEwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*E3rZ-ET_Z8qEO6Eo3QIyeA.png" /></p>

<p>1階では<a href="/posts/z-度旅行遊記/九州自由行-福岡-長崎-熊本を巡る10日間の独り旅ガイド-d78e0b15a08a/">くまモン</a>のイベントがあります。</p>

<p><img src="/assets/aacd5f5cacd1/1*RW5sFcypjE_mj4CVwxKotQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="852" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg1MiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*RW5sFcypjE_mj4CVwxKotQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ipoT-8QkWmfXhInjaK3Q2w.webp" alt="" loading="lazy" decoding="async" width="1330" height="2364" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzMwIiBoZWlnaHQ9IjIzNjQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*ipoT-8QkWmfXhInjaK3Q2w.jpeg" /></p>

<p>おそらく休日のため、イベントが多く、Kiddy Landの外にもカナヘラの撮影イベントがありました。（もう一匹のウサギ XD）</p>

<h4 id="1320-神戸へ向かう">13:20 神戸へ向かう</h4>

<p><img src="/assets/aacd5f5cacd1/1*iuobD0lpLgt6UCJ8Wqk3ag.webp" alt="" loading="lazy" decoding="async" width="1400" height="1012" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMTIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*iuobD0lpLgt6UCJ8Wqk3ag.png" /></p>

<p>地下街で少し迷ってから、大阪梅田地下鉄駅を見つけ、阪急神戸線に乗って神戸三宮（阪急）へ向かいました。</p>

<h4 id="1350-神戸到着">13:50 神戸到着</h4>

<p>まだ時間が早いので、まずは「<a href="https://maps.app.goo.gl/fspZDr7MyGMpT24r6" target="_blank">神戸どうぶつ王国</a>」でカピバラを探す予定です。</p>

<p><img src="/assets/aacd5f5cacd1/1*L_861E8BgHXpjDqG7B-ExA.webp" alt="" loading="lazy" decoding="async" width="1200" height="816" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgxNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*L_861E8BgHXpjDqG7B-ExA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*wkKdFGjiN_C6aGWTNSNxXA.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*wkKdFGjiN_C6aGWTNSNxXA.jpeg" /></p>

<p>Googleマップは「新交通ポートアイランド線」に乗るように案内しましたが、地下街で長い間迷って対応する案内標識が見つかりませんでした。（迷子の日）</p>

<p><img src="/assets/aacd5f5cacd1/1*OAOZe3cdGLU6r_6Nv2QEww.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OAOZe3cdGLU6r_6Nv2QEww.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Rx_UFhPm-pM6Nxn2DTKx6w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*Rx_UFhPm-pM6Nxn2DTKx6w.jpeg" /></p>

<p>改札を出て初めて気づいたのは、まさに空を走る路線だったということ。2階の三宮駅から入場しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*yWTsJjuy_Xn01e9Lus8YOw.webp" alt="" loading="lazy" decoding="async" width="1400" height="585" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjU4NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*yWTsJjuy_Xn01e9Lus8YOw.png" /></p>

<p>駅には多くの人がいて、後で知ったのですが、今日はちょうど<a href="https://zh-tw.kobe-marathon.net/2024/global/" target="_blank">神戸マラソン</a>の日でした。</p>

<p>迷子の日…ちょうど来た車に気づかずに間違った車に乗ってしまい、北埠頭行きの車に乗ってしまった。ここから悲劇が始まった。</p>

<p><img src="/assets/aacd5f5cacd1/1*sURfSLVO2IkE2QPTq3zm7g.webp" alt="" loading="lazy" decoding="async" width="1265" height="286" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjY1IiBoZWlnaHQ9IjI4NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*sURfSLVO2IkE2QPTq3zm7g.png" /></p>

<blockquote>
  <p><strong><em>神戸動物王国に行くには神戸空港行きに乗ってください。北埠頭行きに乗ると北埠頭で折り返して神戸に戻ります。</em></strong> <em>⚠️⚠️⚠️</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*Yb1jgpn5nKnHA0to0JlBvA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*Yb1jgpn5nKnHA0to0JlBvA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*z8eEqxV_DQKM1FGLRxRU7A.webp" alt="" loading="lazy" decoding="async" width="879" height="1096" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzkiIGhlaWdodD0iMTA5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*z8eEqxV_DQKM1FGLRxRU7A.png" /></p>

<p>神戸マラソンでは高架道路が封鎖されて走れます。この地下鉄は北捷文湖線と同様に、初期のタイヤ式地下鉄です。</p>

<h4 id="1420-間違った電車に乗っていることに気づき中埠頭で降車">14:20 間違った電車に乗っていることに気づき、中埠頭で降車</h4>

<p><img src="/assets/aacd5f5cacd1/1*IGsTOnGQ2wiFBthumdIybw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*IGsTOnGQ2wiFBthumdIybw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*_BOkMH5_0AnTJcaZCtwUtg.webp" alt="" loading="lazy" decoding="async" width="553" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTMiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_BOkMH5_0AnTJcaZCtwUtg.jpeg" /></p>

<p>ここで様子がおかしいと感じて途中下車し、Google Mapは市民広場駅まで歩いて次の電車に乗ることを勧めました。</p>

<p><img src="/assets/aacd5f5cacd1/1*wCBuXOfGc6fSMVTM1MLZ_w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*wCBuXOfGc6fSMVTM1MLZ_w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*g8uGboUzgjpperWLcaCe-A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*g8uGboUzgjpperWLcaCe-A.jpeg" /></p>

<p>おそらく埋立地の港湾エリアだからか、ここはとても寂しくて歩くと遠く感じます。</p>

<p><img src="/assets/aacd5f5cacd1/1*ZyXQTkEYvXAbIv0TVUgCzQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="978" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk3OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ZyXQTkEYvXAbIv0TVUgCzQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*5ZyBkEGQ_NiYON5ofd9faw.webp" alt="" loading="lazy" decoding="async" width="1200" height="876" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*5ZyBkEGQ_NiYON5ofd9faw.png" /></p>

<p>市民広場前駅に急いで行くと、なぜこんなに賑やかなのかと思ったら、神戸マラソンのゴールイベント会場でした。</p>

<p><img src="/assets/aacd5f5cacd1/1*ULve9yF_dxl_KN_wjREO0g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ULve9yF_dxl_KN_wjREO0g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YGSebYSQT5maJTHBLgu2xA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YGSebYSQT5maJTHBLgu2xA.jpeg" /></p>

<blockquote>
  <p><em>悲劇的に2人が多すぎてこの駅に入れず、さらに進んで南公園駅まで行く必要があった。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*2Gq2LpscnF2cQqBST6ueyA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*2Gq2LpscnF2cQqBST6ueyA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*gW7yF6pDt4RDQIzLnd-f0A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*gW7yF6pDt4RDQIzLnd-f0A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*HoUGLVRBxl2s45E40BMLGQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*HoUGLVRBxl2s45E40BMLGQ.jpeg" /></p>

<p>南公園駅まで歩いて、あと一駅で着くので、面倒で地下鉄に乗らずに直接神戸どうぶつ王国へ歩いて行きました…</p>

<p>前述の通り、あまりにも寂しいため歩くと遠く感じますが、実際に中埠頭から歩いて2キロ（約30分）あります。</p>

<h4 id="1450-神戸どうぶつ王国に到着">14:50 神戸どうぶつ王国に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*HzgFgMtmQ3Sw6piVC4Mblg.webp" alt="" loading="lazy" decoding="async" width="1400" height="977" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk3NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*HzgFgMtmQ3Sw6piVC4Mblg.png" /></p>

<p>入場券：2,200円</p>

<p><img src="/assets/aacd5f5cacd1/1*bwUP-L5-s7kjH5O2TAcf6g.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*bwUP-L5-s7kjH5O2TAcf6g.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*jqf3mJy-K5HtBDnG0lcThA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*jqf3mJy-K5HtBDnG0lcThA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*PYEx2kx73xmpbMrGZNTcqg.webp" alt="コウノトリ、テン、レッサーパンダ" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*PYEx2kx73xmpbMrGZNTcqg.jpeg" /></p>

<p>コウノトリ、テン、レッサーパンダ</p>

<p>神戸どうぶつ王国は半屋内・半屋外ですが、館内の動線がよく整備されていて、さまざまな鳥や動物がいます。多くは間近で触れ合うことができ、親子で半日過ごすのに最適です。動物の状態は姫路市立動物園よりずっと良く、環境もとても清潔です。</p>

<h4 id="カピバラ">カピバラ</h4>

<p><img src="/assets/aacd5f5cacd1/1*DK2DEH8iPJmiTyDHldeqHQ.webp" alt="" loading="lazy" decoding="async" width="876" height="1087" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzYiIGhlaWdodD0iMTA4NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*DK2DEH8iPJmiTyDHldeqHQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*CqjDL7S99NtLuamD8V3A0w.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*CqjDL7S99NtLuamD8V3A0w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*XtvMffuoulVGOt0AK88BbQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*XtvMffuoulVGOt0AK88BbQ.jpeg" /></p>

<p>ここに来た目的は達成しました。カピバラに触れてみました。とても太っていて、毛はざらざらしていてまるでほうきのようでした。</p>

<p><img src="/assets/aacd5f5cacd1/1*AoazZpBcYuh-LpiZLCk6fw.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*AoazZpBcYuh-LpiZLCk6fw.jpeg" /></p>

<p>みんな怠けた顔をしていて、仕事に行かなくていいなんて最高！</p>

<p><img src="/assets/aacd5f5cacd1/1*Dui-4l3rOZkGVjVuEAjqZw.webp" alt="" loading="lazy" decoding="async" width="569" height="764" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjkiIGhlaWdodD0iNzY0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*Dui-4l3rOZkGVjVuEAjqZw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*a0JZ_DEQph3dAI-Mlzhxvw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*a0JZ_DEQph3dAI-Mlzhxvw.jpeg" /></p>

<p>太っているためか、現在は場内での餌やりは禁止されており、場外からの餌や物を頭に置くこともできません。</p>

<p>別のエリアにはカンガルーや羊と間近で触れ合える場所もあります。</p>

<p><img src="/assets/aacd5f5cacd1/1*D4K3htSuQ7vwCDGqizRLrg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*D4K3htSuQ7vwCDGqizRLrg.jpeg" /></p>

<p>触る前と触った後は、必ず手を洗いましょう。</p>

<p><img src="/assets/aacd5f5cacd1/1*A540bEA8Z1WvYv2BZZB6XQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*A540bEA8Z1WvYv2BZZB6XQ.jpeg" /></p>

<p>もう一匹アザラシがいますが、場所が狭そうでずっとぐるぐる回っていましたQQ</p>

<p><img src="/assets/aacd5f5cacd1/1*V3fEMjXiFUrjBW01U3hWOw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*V3fEMjXiFUrjBW01U3hWOw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*3YjSHmLP5S50YO2yFl6aBg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*3YjSHmLP5S50YO2yFl6aBg.jpeg" /></p>

<p>ペンギンの餌やり（整理券が必要です）。</p>

<p><img src="/assets/aacd5f5cacd1/1*N2xebJcxnHYGn8e1rTojCw.webp" alt="" loading="lazy" decoding="async" width="1330" height="2364" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMzMwIiBoZWlnaHQ9IjIzNjQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*N2xebJcxnHYGn8e1rTojCw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*a_o37TUg0JELGpeHIlmrZQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*a_o37TUg0JELGpeHIlmrZQ.jpeg" /></p>

<p>かわいい小さなカワウソの家族が、ずっとキューキュー鳴いています。</p>

<p><img src="/assets/aacd5f5cacd1/1*CuP3tdfDMluPWnxc-9Wq1A.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*CuP3tdfDMluPWnxc-9Wq1A.jpeg" /></p>

<p>カワウソのところにマレーバクが一匹いますが、あまり相手にされていません QQ</p>

<p><img src="/assets/aacd5f5cacd1/1*JNkNZEh__ouaMUnwCCIdNg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*JNkNZEh__ouaMUnwCCIdNg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*xniRR-ET-l2adsy9Yd30Mw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*xniRR-ET-l2adsy9Yd30Mw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*aW3oScEuZgY3pgBar7RWrA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*aW3oScEuZgY3pgBar7RWrA.jpeg" /></p>

<p>オオハシとフクロウ、そして足元に現れるキジ。（歩くときは踏まないように注意⚠️）</p>

<p><img src="/assets/aacd5f5cacd1/1*yEYyShOUZxvFBGvis-Vrow.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*yEYyShOUZxvFBGvis-Vrow.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*cgKffBX23EMZtHYSuLmf9w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*cgKffBX23EMZtHYSuLmf9w.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*7Ic9m_24xoIpTB-TS_o_wg.webp" alt="ジュリアン王と食いしん坊の同僚ペリカン、夜行館のフクロウもいます" loading="lazy" decoding="async" width="675" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NzUiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*7Ic9m_24xoIpTB-TS_o_wg.jpeg" /></p>

<p>ジュリアン王は、同僚のペリカンと夜行性のフクロウも飼っています。</p>

<p><img src="/assets/aacd5f5cacd1/1*zUgtU9kQCKScJsprv1NTQQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="964" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk2NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*zUgtU9kQCKScJsprv1NTQQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*pM5AvtCSA_REaZKTOYODgA.webp" alt="" loading="lazy" decoding="async" width="860" height="1091" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjAiIGhlaWdodD0iMTA5MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*pM5AvtCSA_REaZKTOYODgA.png" /></p>

<p>室内にはウサギやネコ、イヌと触れ合えるエリア（整理券が必要）、飲食店、土産物店などがあります。</p>

<p>全体的にとても良い体験でした！</p>

<h4 id="1550-出発神戸へ戻る準備">15:50 出発、神戸へ戻る準備</h4>

<p>主にカピバラに会いに来ましたが、時間があまりなかったのであまり長く滞在しませんでした。</p>

<p><img src="/assets/aacd5f5cacd1/1*yfpUfEWTujRfFn1SLBi8aQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*yfpUfEWTujRfFn1SLBi8aQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*42N4yOOTADXSR3TnaE0foA.webp" alt="" loading="lazy" decoding="async" width="1400" height="983" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*42N4yOOTADXSR3TnaE0foA.png" /></p>

<h4 id="-1605-神戸三宮駅に到着">~= 16:05 (神戸)三宮駅に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*oNUQVDNJXP_zpuS0vPWIWA.webp" alt="" loading="lazy" decoding="async" width="872" height="1098" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzIiIGhlaWdodD0iMTA5OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*oNUQVDNJXP_zpuS0vPWIWA.png" /></p>

<p>神戸マラソンのため、駅を出る人が非常に多いです。</p>

<p><img src="/assets/aacd5f5cacd1/1*92IdBTMJ1Z1AyzHdCQVNHA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*92IdBTMJ1Z1AyzHdCQVNHA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*g-zbhehAAcO3tmvdJ6Dotw.webp" alt="" loading="lazy" decoding="async" width="858" height="1081" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NTgiIGhlaWdodD0iMTA4MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*g-zbhehAAcO3tmvdJ6Dotw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*4kvY1I-JyKoMbo6Xo3Mg6A.webp" alt="" loading="lazy" decoding="async" width="877" height="1079" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzciIGhlaWdodD0iMTA3OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4kvY1I-JyKoMbo6Xo3Mg6A.png" /></p>

<p>食事の時間までまだ1時間以上あるので、先に神戸三宮周辺を散策します。いつものようにガチャガチャとKiddy Landを探しに行きます。</p>

<p><img src="/assets/aacd5f5cacd1/1*LAu0vz0PiOzK3QC8xQbeJg.webp" alt="" loading="lazy" decoding="async" width="872" height="1076" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzIiIGhlaWdodD0iMTA3NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*LAu0vz0PiOzK3QC8xQbeJg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*eDM9G1Lrm5nQLnusWKD7uA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*eDM9G1Lrm5nQLnusWKD7uA.jpeg" /></p>

<p>神戸のKiddy Landはあまり人がいませんでしたが、ジイカワのグッズは少なく、欲しかったウサギのパジャマは見つかりませんでした。</p>

<p><img src="/assets/aacd5f5cacd1/1*Cmt7wQ4UV4cYAaTNzxvgHA.webp" alt="" loading="lazy" decoding="async" width="878" height="1102" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzgiIGhlaWdodD0iMTEwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Cmt7wQ4UV4cYAaTNzxvgHA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*q7C947BYHvNxBDhPSGG6uQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="819" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgxOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*q7C947BYHvNxBDhPSGG6uQ.png" /></p>

<p>Center Plazaは少し古いですが、多くの店舗があり、買い物が楽しめます。</p>

<p><img src="/assets/aacd5f5cacd1/1*8vFujFuXpB65kosAzXrtkw.webp" alt="" loading="lazy" decoding="async" width="1400" height="986" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk4NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*8vFujFuXpB65kosAzXrtkw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*XD7jraHi5_yQZfB7YAkv9Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="959" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk1OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*XD7jraHi5_yQZfB7YAkv9Q.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*WlCIdUIpqTHUN4jwg1x_Hg.webp" alt="" loading="lazy" decoding="async" width="820" height="1122" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MjAiIGhlaWdodD0iMTEyMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*WlCIdUIpqTHUN4jwg1x_Hg.png" /></p>

<p>2階に行ってガチャガチャを探し、リサイクルショップで欲しいウサギグッズがあるか見てみる。</p>

<p><img src="/assets/aacd5f5cacd1/1*3AtESgoEYKHf6RFMBy7a4A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*3AtESgoEYKHf6RFMBy7a4A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*DhlS3byoBALyjqUNQNZlqw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*DhlS3byoBALyjqUNQNZlqw.jpeg" /></p>

<p>信長書店というお店があり、お守りを買って友達に送ることができます。ふふ。</p>

<h4 id="1700-神戸牛-吉祥吉">~=17:00 <a href="https://maps.app.goo.gl/8UcmAfUDGpH8F1PX8" target="_blank">神戸牛 吉祥吉</a></h4>

<p><img src="/assets/aacd5f5cacd1/1*_kTtTzMcYzgucSSbZBpOMg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_kTtTzMcYzgucSSbZBpOMg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YeGNnRYe3W2AId3Ey5Xoxg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YeGNnRYe3W2AId3Ey5Xoxg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*AF8Ium09DuuXVdb6wgirtQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*AF8Ium09DuuXVdb6wgirtQ.jpeg" /></p>

<p>B1には神戸牛の吉祥吉があり、ほぼ5時前に夕食を食べに来ました。</p>

<p>まだ時間が早く、あまり人がいません。店主は私が台湾から来たと聞いてとても親切にしてくれました。この食事も神戸に来た目的の一つで、<strong>良い食事をする — 神戸牛</strong>、そうでなければ数日間ほとんど適当に食べていました。</p>

<p><img src="/assets/aacd5f5cacd1/1*TplkGy7shiHlWAHyLf9-KQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="824" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*TplkGy7shiHlWAHyLf9-KQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*0ufGhslTqU6l0UUlsFCOCg.webp" alt="" loading="lazy" decoding="async" width="822" height="626" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MjIiIGhlaWdodD0iNjI2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*0ufGhslTqU6l0UUlsFCOCg.png" /></p>

<p>「神戸牛赤身肉ステーキ 220g」7,700円（税抜⚠️、会計時に税込）を注文し、セットメニュー（サラダ、ご飯、スープ）と生ビールを追加しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*794jNjGugkDnsJOPEdOJZw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*794jNjGugkDnsJOPEdOJZw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*xSB_UvOX-MwvXzzmDx-KoQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*xSB_UvOX-MwvXzzmDx-KoQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*H55tOkGS36r6WTGAqT560w.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*H55tOkGS36r6WTGAqT560w.jpeg" /></p>

<p>レタスはさっぱりしていて、スープは牛肉スープで、とても美味しかったです。</p>

<p><img src="/assets/aacd5f5cacd1/1*MJLdfXQZoH_4vUy0KUOq5w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1002" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMDIiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*MJLdfXQZoH_4vUy0KUOq5w.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*MUe5xLDpu4wLU2OCnrddTw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*MUe5xLDpu4wLU2OCnrddTw.jpeg" /></p>

<p>肉は柔らかく、ジューシーで肉の旨味がしっかり感じられます。昨日食べた神戸牛と比べて、これこそが本物の神戸牛の味です。</p>

<blockquote>
  <p><em>でも正直に言うと、私はやはり鉄板焼きの方が洋食より好きです。</em></p>
</blockquote>

<p>最終支払い額：<code class="language-plaintext highlighter-rouge">$2,158 台湾ドル</code>。</p>

<h4 id="1740-食事を終えて出発神戸タワーへ向かう">17:40 食事を終えて出発、神戸タワーへ向かう</h4>

<p>食事の後、海岸線の旧居留地、大丸前駅まで歩き、一駅電車に乗ってから神戸タワーへ徒歩で向かいます。</p>

<p><img src="/assets/aacd5f5cacd1/1*ynQiJ9mgKhOxFdSUESJFnQ.webp" alt="" loading="lazy" decoding="async" width="873" height="1095" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzMiIGhlaWdodD0iMTA5NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ynQiJ9mgKhOxFdSUESJFnQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*_BKRsKmQrLdl9fLPgOrFaQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_BKRsKmQrLdl9fLPgOrFaQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*4l2DyckNmvx97IuF256JUg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4l2DyckNmvx97IuF256JUg.jpeg" /></p>

<p>神戸は姫路に比べてとても賑やかで、たくさんのデパートがあります。</p>

<p>新長田行きに乗り、次の港元町で下車します。</p>

<h4 id="1805-神戸タワー周辺に到着">18:05 神戸タワー周辺に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*441FBjZsUDMXDMQxz8XCmg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*441FBjZsUDMXDMQxz8XCmg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*wH_baSj-1o9q5GyFZ97-xg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*wH_baSj-1o9q5GyFZ97-xg.jpeg" /></p>

<p><a href="/posts/z-度旅行遊記/京阪神自由行-8日間の京都-大阪-神戸旅行完全ガイド-食事-宿泊-交通情報を網羅-76d66c2e34af/">去年来たときは修理中でした</a>、現在は完全に開放されています。</p>

<p><img src="/assets/aacd5f5cacd1/1*NdyL8AiQtaLIkZfb54dFVA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*NdyL8AiQtaLIkZfb54dFVA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*cD32qAyEg7AOlZJg04FM_w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*cD32qAyEg7AOlZJg04FM_w.jpeg" /></p>

<p>神戸港は港町の雰囲気があり、機会があれば神戸で一泊することを検討したいです。</p>

<p>今回はざっと見て回っただけです。</p>

<h4 id="1830-神戸中華街に戻る">18:30 神戸中華街に戻る</h4>

<p>神戸駅に戻る途中で、まず中華街へ行き、<a href="https://frantz.co.jp/en/" target="_blank">Kobe Frantz チョコレートお土産</a> を買いました。</p>

<p><img src="/assets/aacd5f5cacd1/1*XjaKzeVqxVLXk_MQFlABzw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*XjaKzeVqxVLXk_MQFlABzw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*D2ge3h9VtwH0vCO8-rT6kQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*D2ge3h9VtwH0vCO8-rT6kQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*usONmjglsnKER-HS5DS2yQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*usONmjglsnKER-HS5DS2yQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Y_VKoWARSlj-ZuQHwEYbCQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Y_VKoWARSlj-ZuQHwEYbCQ.jpeg" /></p>

<h4 id="jr元町駅に戻る">JR元町駅に戻る</h4>

<p><img src="/assets/aacd5f5cacd1/1*HFFt6e3ORaTBS_A2xfk_Mw.webp" alt="" loading="lazy" decoding="async" width="1200" height="791" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc5MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*HFFt6e3ORaTBS_A2xfk_Mw.png" /></p>

<p>JR元町駅に注意してください。阪神電車の元町駅に行かないようにしてください。</p>

<h4 id="1853-快速電車で姫路方面の網干行きに乗り神戸兵庫へ向かう">18:53 快速電車で姫路方面の網干行きに乗り、神戸（兵庫）へ向かう</h4>

<p><img src="/assets/aacd5f5cacd1/1*kQMXFTC_jkFXbQrLjTKawA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*kQMXFTC_jkFXbQrLjTKawA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*CIaO_bZsDuNIThM4GNUXqA.webp" alt="" loading="lazy" decoding="async" width="384" height="351" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzODQiIGhlaWdodD0iMzUxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*CIaO_bZsDuNIThM4GNUXqA.png" /></p>

<h4 id="1857-同じホームの反対側で乗り換え-新快速-湖西線経由-網干行き">18:57 同じホームの反対側で乗り換え 新快速 湖西線経由 網干行き</h4>

<blockquote>
  <p><strong><em>乗り換えが速くて20分で到着</em></strong> <em>、松本清の免税時間終了前に姫路で唯一の薬局に間に合ってよかった。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*LL8pEAjsoOyIBY7Zng5EOg.webp" alt="" loading="lazy" decoding="async" width="873" height="1100" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzMiIGhlaWdodD0iMTEwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*LL8pEAjsoOyIBY7Zng5EOg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*GNDjeJjhEgixMjH69bSMuQ.webp" alt="" loading="lazy" decoding="async" width="872" height="1106" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzIiIGhlaWdodD0iMTEwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*GNDjeJjhEgixMjH69bSMuQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*zEh8247pPwlJJShPWXRhNg.webp" alt="" loading="lazy" decoding="async" width="867" height="1096" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjciIGhlaWdodD0iMTA5NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*zEh8247pPwlJJShPWXRhNg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*kNw192v7znWE0utpE0cVGA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*kNw192v7znWE0utpE0cVGA.jpeg" /></p>

<p>この列車の車両も隣の開閉ボタンを押さないとドアが開かず、車両同士は区切られています。</p>

<h4 id="1934-姫路到着">19:34 姫路到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*JGEsWM6ZsBJhQ9MDEFgjyg.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*JGEsWM6ZsBJhQ9MDEFgjyg.jpeg" /></p>

<h4 id="1945-姫路-piole-のマツモトキヨシで薬妝を購入">19:45 姫路 Piole のマツモトキヨシで薬妝を購入</h4>

<p><img src="/assets/aacd5f5cacd1/1*1yNFLnhhhRjr32KRjndzZQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1yNFLnhhhRjr32KRjndzZQ.jpeg" /></p>

<blockquote>
  <p><em>営業時間は21:00までですが、<strong>免税対応時間は20:30まで</strong>です。⚠️⚠️⚠️</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*gEwopdiZt9hWS18pwDmbog.webp" alt="超ミニサイズのカップヌードルを買いました" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*gEwopdiZt9hWS18pwDmbog.jpeg" /></p>

<p>超ミニサイズのカップヌードルを買いました</p>

<p><img src="/assets/aacd5f5cacd1/1*XIL4YdSSE1aSMvOCfo_Eog.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*XIL4YdSSE1aSMvOCfo_Eog.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*1UO4_sG-Z1vARToCEpeSGQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1UO4_sG-Z1vARToCEpeSGQ.jpeg" /></p>

<p>日本での最後の夜、ホテルで食べたり飲んだりしながら夜食を楽しむ。ビールも。 （この団子はふわふわの食感…）</p>

<blockquote>
  <p><strong><em>おやすみ、姫路。</em></strong></p>
</blockquote>

<h3 id="7日目1118-月曜日岡山帰路">7日目（11/18 月曜日）岡山、帰路</h3>

<h4 id="0830-おはよう姫路">08:30 おはよう姫路</h4>

<p><img src="/assets/aacd5f5cacd1/1*gIylwTEdczfgkIyCgRg-PQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*gIylwTEdczfgkIyCgRg-PQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*ZfhXzMRapc-5g77Nrk7GCQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*ZfhXzMRapc-5g77Nrk7GCQ.jpeg" /></p>

<p>最後に姫路の朝をもう一度見る。</p>

<p><img src="/assets/aacd5f5cacd1/1*KR95SMQ2Nrdf6lK0wxqEcg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*KR95SMQ2Nrdf6lK0wxqEcg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*u1yIgbMQGfGFLOJ4fsFBbA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*u1yIgbMQGfGFLOJ4fsFBbA.jpeg" /></p>

<p>新幹線駅に到着し、08:52発の新幹線で岡山へ向かう準備をする。</p>

<h4 id="0852の新幹線自由席で岡山へ向かう">08:52の新幹線自由席で岡山へ向かう</h4>

<p><img src="/assets/aacd5f5cacd1/1*WzQVvLKiQSx-5LXpw75O3w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*WzQVvLKiQSx-5LXpw75O3w.jpeg" /></p>

<h4 id="0913-岡山駅に到着">09:13 岡山駅に到着</h4>

<p>新幹線で約21分で岡山駅に着きますが、今回は時間が足りず、<a href="https://medium.com/ztravel/%E9%81%8A%E8%A8%98-2023-%E5%BB%A3%E5%B3%B6%E5%B2%A1%E5%B1%B1-6-%E6%97%A5%E9%81%8A-31b9b3a63abc?source=collection_home---4------2-----------------------" target="_blank">広島再訪</a> はできませんでした。</p>

<p><img src="/assets/aacd5f5cacd1/1*PgFJG7RNh8w5f4pK5Dv6Eg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*PgFJG7RNh8w5f4pK5Dv6Eg.jpeg" /></p>

<p>前回と同様に岡山駅西口の空港行きバス乗り場へ直接向かいます。ここにはコインロッカーがあり荷物を預けられ、トイレもあります（この時間は百貨店がまだ開いておらず、トイレは少なめです）。</p>

<h4 id="0930-岡山駅のマクドナルドで最近台湾で話題のパンケーキバーガーを食べる">09:30 岡山駅のマクドナルドで、最近台湾で話題の「パンケーキバーガー」を食べる</h4>

<p><img src="/assets/aacd5f5cacd1/1*1O8uNrClegWyQoAJE12e5g.webp" alt="" loading="lazy" decoding="async" width="838" height="809" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzgiIGhlaWdodD0iODA5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*1O8uNrClegWyQoAJE12e5g.png" /></p>

<p>日本語がわからず間違えそうになりましたが、選ぶべきは「マックグリドル」で、これがパンケーキシリーズです。</p>

<blockquote>
  <p><em>日本のマクドナルドの朝食時間は10:30までです。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*OOoRAGeCSlq2AhtBBs3ZaA.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OOoRAGeCSlq2AhtBBs3ZaA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*tuExEIAQs1IIAede34Odqg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*tuExEIAQs1IIAede34Odqg.jpeg" /></p>

<p>朝10時頃食事を終え、特に行きたい場所はありません。</p>

<p><img src="/assets/aacd5f5cacd1/1*17imSbehBjflWDXLWBedlQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*17imSbehBjflWDXLWBedlQ.jpeg" /></p>

<p><a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/">前回はすでに岡山城と吉備津神社に行ったので</a>、最後の時間に岡山AEONモールを散策しました。</p>

<p><img src="/assets/aacd5f5cacd1/1*j6NZ7W08WVWsntCa7qvN6A.webp" alt="岡山アートフェスティバル" loading="lazy" decoding="async" width="682" height="506" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2ODIiIGhlaWdodD0iNTA2Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*j6NZ7W08WVWsntCa7qvN6A.png" /></p>

<p><a href="https://forestartfest-okayama.jp/" target="_blank">岡山アートシーズン</a></p>

<p>今年岡山では<a href="https://forestartfest-okayama.jp/" target="_blank">アートフェスティバル</a>が開催されています。</p>

<p><img src="/assets/aacd5f5cacd1/1*dhgBrvzJrFsPimXmsJb_QQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*dhgBrvzJrFsPimXmsJb_QQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YEmu3f0rStKaWXCl890OSQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YEmu3f0rStKaWXCl890OSQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*HaQeBv92EgDp2qdq3EHFvQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*HaQeBv92EgDp2qdq3EHFvQ.jpeg" /></p>

<p>工事中の岡山駅と、一時的に駅の隣に移された桃太郎。</p>

<p><img src="/assets/aacd5f5cacd1/1*_aly6JVMgGDzW4BogUg9Wg.webp" alt="" loading="lazy" decoding="async" width="878" height="1101" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzgiIGhlaWdodD0iMTEwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*_aly6JVMgGDzW4BogUg9Wg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*6bKTUuYl1MMeXhkb2JKOLg.webp" alt="" loading="lazy" decoding="async" width="882" height="1097" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4ODIiIGhlaWdodD0iMTA5NyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*6bKTUuYl1MMeXhkb2JKOLg.png" /></p>

<p>地下街を通ってAEON MALLのB2へ渡ると、こちらにもマクドナルドがあります。</p>

<p><img src="/assets/aacd5f5cacd1/1*I7cFknifEeInNlJfK7UYSw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*I7cFknifEeInNlJfK7UYSw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*h_77ECXhHjNHSl7Lr8L7-Q.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*h_77ECXhHjNHSl7Lr8L7-Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*nvJY17geWnC69iCT0kQHrg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*nvJY17geWnC69iCT0kQHrg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*BlcO-BaPAFCkd_q9L30Etw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*BlcO-BaPAFCkd_q9L30Etw.jpeg" /></p>

<p>ここはとても広くて見どころが多く、ほとんどすべてのブランドが揃っています。</p>

<p><img src="/assets/aacd5f5cacd1/1*vjssm5svEoPfePGcNgElCg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*vjssm5svEoPfePGcNgElCg.jpeg" /></p>

<p>食事をしたり、お土産を買ったりする場所も（B1-B2階）あります。</p>

<p><img src="/assets/aacd5f5cacd1/1*8oOH2Pe4c_SbgDzwoR21Yg.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*8oOH2Pe4c_SbgDzwoR21Yg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*NapTm7rBZ4qVZ7EpNqr7xg.webp" alt="" loading="lazy" decoding="async" width="1200" height="866" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijg2NiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*NapTm7rBZ4qVZ7EpNqr7xg.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YClpxnjnyZQuS_ZNi6ZvvQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1008" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwMDgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*YClpxnjnyZQuS_ZNi6ZvvQ.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*HJ4J2jAs8mruW6BZYvyWcA.webp" alt="" loading="lazy" decoding="async" width="602" height="1306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDIiIGhlaWdodD0iMTMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*HJ4J2jAs8mruW6BZYvyWcA.jpeg" /></p>

<p>引き続きガチャを探しましたが、欲しかった電車ボタンのガチャは見つからず、諦めました…もう販売されていないようです。</p>

<p><img src="/assets/aacd5f5cacd1/1*HdWGWOOs9agTb9qWYaiqiQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*HdWGWOOs9agTb9qWYaiqiQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*hK5tJ8UD4aNoz9LNTYBWyA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*hK5tJ8UD4aNoz9LNTYBWyA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*MQnwEbWs96IBpBEKW7IB4w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*MQnwEbWs96IBpBEKW7IB4w.jpeg" /></p>

<p>吉伊カワを販売している店舗もいくつかあります。</p>

<h4 id="1100-昼食の準備">~=11:00 昼食の準備</h4>

<blockquote>
  <p><strong><em>あまりお腹は空いていませんが、午後の待機時間と虎航の機内食がないため、やはり食べる必要があります。</em></strong> <em>⚠️⚠️⚠️</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*s8axzlQR2pkJASqoyiPjQg.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*s8axzlQR2pkJASqoyiPjQg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*3JEFC2MwRYJbT7WR4kb2Sg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*3JEFC2MwRYJbT7WR4kb2Sg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*uxodtgWIX2tokvA8GANlBQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*uxodtgWIX2tokvA8GANlBQ.jpeg" /></p>

<p>上の階には食事の選択肢がたくさんあります。</p>

<p><img src="/assets/aacd5f5cacd1/1*8OX9V42Q-S0S7W-1Ve7n6A.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*8OX9V42Q-S0S7W-1Ve7n6A.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*mIUREsw2cy1DfnAuxi9lWg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*mIUREsw2cy1DfnAuxi9lWg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*vAiLB635e_VNF1BrY7U3ZA.webp" alt="**豚ステーキ専門店 B 岡山店**" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*vAiLB635e_VNF1BrY7U3ZA.jpeg" /></p>

<p><a href="https://tabelog.com/okayama/A3301/A330101/33018608/" target="_blank"><strong>豚ステーキ専門店 B 岡山店</strong></a></p>

<p>鉄板とんかつをメインにした店を選びました。</p>

<p><img src="/assets/aacd5f5cacd1/1*f9-cymGYzbWqmSgVSwht8Q.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*f9-cymGYzbWqmSgVSwht8Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*-8Sx-7tZ5l-DPua6GOunTA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*-8Sx-7tZ5l-DPua6GOunTA.jpeg" /></p>

<p>鉄板とんかつ定食（200g）と生ビールを注文しました。合計で <code class="language-plaintext highlighter-rouge">2,178 円</code> でした。</p>

<p><img src="/assets/aacd5f5cacd1/1*rT1vHotHA_BsYMp5BFadUQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*rT1vHotHA_BsYMp5BFadUQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*weW08CNKF-sFY48mz-Qw7g.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*weW08CNKF-sFY48mz-Qw7g.jpeg" /></p>

<p>驚いたことに、トンカツが提供されたときは完全に火が通っておらず、約7分火の通り具合でした。評価や紹介を調べると、どうやらこれがこの店の特徴のようです。しかし、私は鉄板が熱いうちに火を通せる部分はしっかり火を通しました。</p>

<blockquote>
  <p><em>本当に美味しくて、ジューシーで肉の旨味がしっかりしていて、噛み切れないこともありません；個人的には昨日の神戸牛に劣らないと思います（多分私はお金持ちの運はないです）。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*4SkncSHSzMb-s7cnwrAqFQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*4SkncSHSzMb-s7cnwrAqFQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*E44bH_Sc3tK3PS-gSzr3jQ.webp" alt="小さなゴミ箱（Airpods Proくらいの大きさ）と子供用バッグ" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*E44bH_Sc3tK3PS-gSzr3jQ.jpeg" /></p>

<p>小さなゴミ箱（AirPods Proとほぼ同じ大きさ）と子供用バッグ</p>

<p>最後に1階の無印良品で少し買い物をして、だいたい12:15に出発しました。</p>

<h4 id="1230-岡山駅に戻る">~=12:30 岡山駅に戻る</h4>

<p>13:00のシャトルバスで岡山空港へ向かいます。</p>

<p><img src="/assets/aacd5f5cacd1/1*g0faLCzFGCjUq6xndxPXCA.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*g0faLCzFGCjUq6xndxPXCA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*wp34SWl53PM47RyotD7_7A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*wp34SWl53PM47RyotD7_7A.jpeg" /></p>

<p>最後にもう一度岡山を見て。</p>

<h4 id="1300-シャトルバスで岡山空港へ移動">~=13:00 シャトルバスで岡山空港へ移動</h4>

<p><img src="/assets/aacd5f5cacd1/1*WQPyQGy5C0nZLfJ-3GIZcA.webp" alt="" loading="lazy" decoding="async" width="869" height="1101" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjkiIGhlaWdodD0iMTEwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*WQPyQGy5C0nZLfJ-3GIZcA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*YD-OAt75d1s69u6qZpWrsw.webp" alt="" loading="lazy" decoding="async" width="872" height="1102" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzIiIGhlaWdodD0iMTEwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*YD-OAt75d1s69u6qZpWrsw.png" /></p>

<p>21番線のここで列に並んで待っていれば、乗り遅れる心配はありません。13:00までに並べば必ず空港まで送ってくれます（満席の場合は臨時バスが追加されます）。</p>

<p>交通系ICカード（Suica）で直接乗降することも、バス停の待合所内で現金を入れて切符を買うこともできます。</p>

<p><img src="/assets/aacd5f5cacd1/1*wZz-iSrK6orko9_30h31gw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*wZz-iSrK6orko9_30h31gw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*2Ey3Ma7iGU0aZcvM-5-KuA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*2Ey3Ma7iGU0aZcvM-5-KuA.jpeg" /></p>

<p>満席のため、12:45に早めに出発しました。</p>

<h4 id="1320-岡山桃太郎空港に到着">~=13:20 岡山桃太郎空港に到着</h4>

<p><img src="/assets/aacd5f5cacd1/1*7gnnl4V4uwpVHg9wq9sliw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*7gnnl4V4uwpVHg9wq9sliw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*Zev8bJycwEj6HruuaPqWyA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Zev8bJycwEj6HruuaPqWyA.jpeg" /></p>

<p>まだかなり早いです。今年は17:30発の便を利用しましたが、去年は15:25発でちょうど良い時間でした。17:30発の場合、今からだとほぼ4時間も待つことになります。</p>

<p><img src="/assets/aacd5f5cacd1/1*EL5tuKai1e95lToFw7agNQ.webp" alt="&lt;https://www.okayama-airport.org/tw/access/bus&gt;" loading="lazy" decoding="async" width="367" height="600" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNjciIGhlaWdodD0iNjAwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*EL5tuKai1e95lToFw7agNQ.png" /></p>

<p><a href="https://www.okayama-airport.org/tw/access/bus" target="_blank">https://www.okayama-airport.org/tw/access/bus</a></p>

<blockquote>
  <p><em>しかし現在は無理です。なぜなら <strong>次の便は15:55発で、空港到着は16:25</strong> だからです。空港は小さく、同時刻の出発便も一便だけで速いですが、渋滞などの影響で16:25に到着する保証は難しいです。私が来た時も渋滞で約30分余分にかかりました。</em></p>
</blockquote>

<blockquote>
  <p><em>今後、岡山空港のシャトルバスの便数が増えるか、または<a href="https://www.facebook.com/groups/207266832755595" target="_blank"><strong>日本自由行討論區</strong></a>のグループでタクシーの相乗り相手を探すしかない。</em></p>
</blockquote>

<blockquote>
  <p><em>他の人のシェアによると、岡山駅から空港までのタクシー料金は約7,000円前後です。</em></p>
</blockquote>

<p><img src="/assets/aacd5f5cacd1/1*BAf8ZKtaE0PZp3CSqHp5oQ.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*BAf8ZKtaE0PZp3CSqHp5oQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*KulgQh4uI3M8GHBzX3_hSw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*KulgQh4uI3M8GHBzX3_hSw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*VrbZuTSIDQztMYoFgjVMOA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*VrbZuTSIDQztMYoFgjVMOA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*WloJT1lwu9sE7K1YY2Lmfg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*WloJT1lwu9sE7K1YY2Lmfg.jpeg" /></p>

<p>空港の近くをぶらぶらしていたら、空港の外に岡山後楽園のミニチュア版と人気の紅葉がありました。</p>

<p><img src="/assets/aacd5f5cacd1/1*DFOrcpULEpM1ZAaCsxVbDQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*DFOrcpULEpM1ZAaCsxVbDQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*OO1rTCEh9kw5aQMfaPk_wQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*OO1rTCEh9kw5aQMfaPk_wQ.jpeg" /></p>

<p>駅の外にも桃太郎の像があり、また空港では保険の購入を親切に勧められました。<strong>今回、本当に自転車にぶつかりそうになりました。⚠️</strong></p>

<p><img src="/assets/aacd5f5cacd1/1*oMmge-1kLe8YMumlz4I-dw.webp" alt="" loading="lazy" decoding="async" width="1200" height="900" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjkwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*oMmge-1kLe8YMumlz4I-dw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*BRsrPzntiPcckzgHSzFOaw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*BRsrPzntiPcckzgHSzFOaw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*JZnvFBhhDjBVHdeEqPDYHw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*JZnvFBhhDjBVHdeEqPDYHw.jpeg" /></p>

<p>国内線は座って休める席がかなりあります。</p>

<p>1階にはお土産屋さんが一軒だけで、他には何もありません。<a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/">去年と同じように</a> 桃の氷餅を一つ買って食べました。</p>

<p><img src="/assets/aacd5f5cacd1/1*PQ1GM0STjbTPYN0p6_S_aA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*PQ1GM0STjbTPYN0p6_S_aA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*dRHe9n0Rpk7sXzbOplk9NA.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*dRHe9n0Rpk7sXzbOplk9NA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*PQ1GM0STjbTPYN0p6_S_aA.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*PQ1GM0STjbTPYN0p6_S_aA.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*MZVip0FtjrMIxj3t3ppxPg.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*MZVip0FtjrMIxj3t3ppxPg.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*1vlNWZvaNY8I47Qydyd9cw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1vlNWZvaNY8I47Qydyd9cw.jpeg" /></p>

<p>2階は改装中で一部の店舗のみ営業しています。 <a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/">去年行けた展望台</a> は閉鎖されているようですが、少なくともお土産店が1軒と飲食店が数軒あります。</p>

<h4 id="1500-チェックイン手続きを開始">~=15:00 チェックイン手続きを開始</h4>

<p><img src="/assets/aacd5f5cacd1/1*lGDYdJexHQY6XkiyPZJOhw.webp" alt="" loading="lazy" decoding="async" width="882" height="1102" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4ODIiIGhlaWdodD0iMTEwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*lGDYdJexHQY6XkiyPZJOhw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*1oLSBw-IwqMJh4-RA81Apg.webp" alt="" loading="lazy" decoding="async" width="1200" height="827" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgyNyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*1oLSBw-IwqMJh4-RA81Apg.png" /></p>

<p>桃太郎空港はとても小さく、他の空港とはチェックインや荷物預けの手続きが異なります。</p>

<blockquote>
  <p><strong><em>こちらは統一された列で、預ける荷物はX線検査を受け、封印シールが貼られます。預け荷物がない場合は不要です（出国前のセキュリティチェックで他の荷物はスキャンされます）。預け荷物がなくてもこの列に並ぶ必要があります</em></strong> <em>列が進んだらスタッフに預け荷物がないことを伝え、そのまま通過します。もしシールを貼った後にスーツケースを開けると、再度スキャンとシール貼り直しが必要です。⚠️⚠️⚠️</em></p>
</blockquote>

<blockquote>
  <p><em>空港のスタッフは中国語が話せる…すごい</em></p>
</blockquote>

<h4 id="1515-チェックイン荷物預け完了">~=15:15 チェックイン＋荷物預け完了</h4>

<p><img src="/assets/aacd5f5cacd1/1*k2WrB1ooYpRa8zSD8A2Dlw.webp" alt="" loading="lazy" decoding="async" width="651" height="1104" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NTEiIGhlaWdodD0iMTEwNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*k2WrB1ooYpRa8zSD8A2Dlw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*MNH21H-7oPaOq-GP_uKUpA.webp" alt="" loading="lazy" decoding="async" width="879" height="1102" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzkiIGhlaWdodD0iMTEwMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*MNH21H-7oPaOq-GP_uKUpA.png" /></p>

<p>今回はあまり買い物をせず、お酒も買っていないのに17kgになってしまいました…しかし、ほとんど手荷物はなく、すべて詰め込みました。</p>

<h4 id="1620-セキュリティチェックと出国手続き開始">~=16:20 セキュリティチェックと出国手続き開始</h4>

<p><img src="/assets/aacd5f5cacd1/1*Wjgk2cV8hkiBkIjxjke6AA.webp" alt="" loading="lazy" decoding="async" width="876" height="1091" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzYiIGhlaWdodD0iMTA5MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*Wjgk2cV8hkiBkIjxjke6AA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*iezQ2KMlAUzJrKjqlHzyLw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1050" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEwNTAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*iezQ2KMlAUzJrKjqlHzyLw.jpeg" /></p>

<p>空港は改修中ですが、それでもガチャガチャがあります。</p>

<p><img src="/assets/aacd5f5cacd1/1*di7LhsC-MYyRIVwYRWVU-Q.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*di7LhsC-MYyRIVwYRWVU-Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*AHTIPdSzU7TJrq1hVeKACg.webp" alt="" loading="lazy" decoding="async" width="774" height="931" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NzQiIGhlaWdodD0iOTMxIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/aacd5f5cacd1/1*AHTIPdSzU7TJrq1hVeKACg.png" /></p>

<p>便が一つだけでも、空港が小さく、スタッフも少なく、路線も一本だけで、検査も厳しいため、保安検査と出国に約20〜30分かかりました。</p>

<p>水を注ぐ場所やゴミを捨てる場所は、ただの箱のようなものです。</p>

<blockquote>
  <p><em>もし15:55発の岡山空港行きバスに間に合えば、16:25に到着予定で、チェックインカウンターはほぼ空いているため、すぐに手続きができ、その後すぐに出国審査の列に並んでも間に合うと思います。</em></p>
</blockquote>

<blockquote>
  <p><em>私たちの便だけなので、チェックイン済みの全員が保安検査を終えるまで出発しないはずです。早く空港に来ても、遅く並んだ人より早く通過できるわけではありません。</em></p>
</blockquote>

<h4 id="1642-搭乗待ち開始">~=16:42 搭乗待ち開始</h4>

<p><img src="/assets/aacd5f5cacd1/1*dZLP9y156IaL2ZYxefWyAQ.webp" alt="" loading="lazy" decoding="async" width="1400" height="1867" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjE4NjciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/aacd5f5cacd1/1*dZLP9y156IaL2ZYxefWyAQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*vb73mCN99CDryoSCqdo_Dw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*vb73mCN99CDryoSCqdo_Dw.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*0-fhLcrfopTMrx9rvE0nYg.webp" alt="" loading="lazy" decoding="async" width="1400" height="965" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk2NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*0-fhLcrfopTMrx9rvE0nYg.png" /></p>

<p>待合室はあまり広くなく、免税店が一軒だけあります。お土産やたばこ、お酒の品揃えは多くありません。</p>

<p><img src="/assets/aacd5f5cacd1/1*SAM-saIjWrap5wL4dAxENQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*SAM-saIjWrap5wL4dAxENQ.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*QCxhYYWHW2RLvZsTgWQ0Sw.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*QCxhYYWHW2RLvZsTgWQ0Sw.jpeg" /></p>

<p>台湾に持ち帰ろうと思っていたピーチウォーターは全部売り切れでした；仕方なく紅茶花伝を1本買いましたが、帰って飲んだらとても美味しくて甘すぎず、もっと買っておけばよかったと後悔しました。</p>

<h4 id="1810-出発40分遅延">~=18:10 出発（40分遅延）</h4>

<p><img src="/assets/aacd5f5cacd1/1*f3Yqp6letQnKZI8spjNn-Q.webp" alt="" loading="lazy" decoding="async" width="1024" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDI0IiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*f3Yqp6letQnKZI8spjNn-Q.jpeg" /></p>

<p><img src="/assets/aacd5f5cacd1/1*PSlGa7hB3SwG6zFHnEVFLQ.webp" alt="" loading="lazy" decoding="async" width="900" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MDAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*PSlGa7hB3SwG6zFHnEVFLQ.jpeg" /></p>

<blockquote>
  <p><strong><em>さようなら岡山、さようなら日本。</em></strong></p>
</blockquote>

<p>機内の隣に座っていたYoutuberのお兄さん「<a href="https://www.youtube.com/@lw.chill2022" target="_blank"><strong>跟著我們一起Chill with us</strong></a>」はとても親切でした。今回は四国に行くそうで、お互いにおすすめの観光地を話し合い、機会があれば私も四国に行きたいと思いました。</p>

<h4 id="1945-台湾に到着10分遅延">19:45 台湾に到着（10分遅延）</h4>

<p>幸いにも10分しか影響がなく、急いで荷物を受け取りバス停へ走った。</p>

<h4 id="2020-台北行きの大有バスへ向かう">20:20 台北行きの大有バスへ向かう</h4>

<p><img src="/assets/aacd5f5cacd1/1*EDhpsb6FiVOOwKoDslj3nA.webp" alt="" loading="lazy" decoding="async" width="879" height="1085" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzkiIGhlaWdodD0iMTA4NSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*EDhpsb6FiVOOwKoDslj3nA.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*63kNa-lLfoQ6uKfjEy9BVw.webp" alt="" loading="lazy" decoding="async" width="875" height="1094" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzUiIGhlaWdodD0iMTA5NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*63kNa-lLfoQ6uKfjEy9BVw.png" /></p>

<p><img src="/assets/aacd5f5cacd1/1*uRb-Shzk65f1cuiiBxd6SQ.webp" alt="" loading="lazy" decoding="async" width="768" height="1024" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NjgiIGhlaWdodD0iMTAyNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/aacd5f5cacd1/1*uRb-Shzk65f1cuiiBxd6SQ.jpeg" /></p>

<p>場所によって異なるバスで帰宅できます。以前は国光バスで直接台北に戻りましたが、今回は大有バスの11番乗り場から新北に戻ります。</p>

<blockquote>
  <p><em>幸運にも悠遊カードの残高が足りず使えなかったため、急いで窓口で現金で切符を買いに行きました（前日に台湾ドルを持っていてよかったです）。結果的にバスに間に合いました。</em></p>
</blockquote>

<h4 id="旅程終了">旅程終了。</h4>

<h3 id="感想まとめ">感想まとめ</h3>

<p>今回の旅程は詰め込みすぎて、多くの場所を駆け足で回りました。特に最初の3日間は移動距離が長く、滞在時間が短かったため、島根の出雲や松江の美しい景色をゆっくり楽しむことができませんでした。もし機会があれば、夕日や紅葉、神迎え神在祭を見にもう一度訪れたいです。</p>

<p>歴史についてもっと知りたい場合は、蘭パパの動画を参考にしてください：</p>

<ol>
  <li>
    <p><a href="https://www.youtube.com/watch?v=cnp9H--KPyY" target="_blank">日本という土地はどうやって誕生したのか？実は生み出された！！\|日本神話\|日本の誕生\|天地開闢\|国産み\|神産み\|大八島国\|イザナギ\|イザナミ\|蘭パパの物語</a></p>
  </li>
  <li>
    <p><a href="https://www.youtube.com/watch?v=W8SjLltb3U4" target="_blank">日本で最もいたずら好きな神、自分の姉から日本皇室の直系の祖先をもうけた！八岐大蛇を斬り、美しい妻を迎え、まさに神界の“神生勝者”！日本最初の和歌が彼の口から出た？！\|日本神話\|須佐之男\|岩戸隠\|八岐大蛇\|稲田姫\|蘭パパの物語</a></p>
  </li>
  <li>
    <p><a href="https://www.youtube.com/watch?v=HbxBcKkfCnk" target="_blank">なぜ一匹のウサギがサメの群れを怒らせたのか？二度の死からの復活を経て、彼はなんと自分の先祖の娘と結婚した！大国主神話｜大国主｜因幡の白ウサギ｜根の国｜日本神話｜蘭パパの物語</a>
<strong>天照大神、大国主神（出雲大社）、因幡の白ウサギの物語が紹介されています。</strong></p>
  </li>
</ol>

<h4 id="山陽-岡山広島エリア旅行記">山陽 岡山広島エリア旅行記</h4>

<ul>
  <li><a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/"><strong>[旅行記] 2023 山陽地域 広島・岡山 6日間自由旅行</strong></a></li>
</ul>

<p>山陽地方の旅行記も参考にできます。時間があれば、山陽と山陰を一緒に楽しむのもおすすめです。</p>

<h4 id="kkday-プロモーション--1">KKday プロモーション 🛒</h4>

<ul>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/153331" target="_blank">日本 JR PASS\|鳥取・松江エリア周遊券\|eMCO 電子チケット</a>
（松江、鳥取松江エリアのみ訪れる場合におすすめ）</p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/20307-jr-sanin-okayama-area-pass?cid=19365" target="_blank"><strong>関西＆山陰エリア鉄道周遊券 JRPass</strong></a>
（岡山空港発着に最適な選択）</p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/137689-japan-high-speed-daily-unlimited-data-japanese-esim?cid=19365" target="_blank"><strong>日本eSIMカード｜毎日高速、総量、無制限データ使い放題プラン</strong></a></p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/20315-jr-sanyo-sanin-area-pass?cid=19365" target="_blank">日本 JR PASS｜山陽＆山陰エリア鉄道周遊券｜eMCO 電子チケット</a>
（一気に山陽山陰エリアを満喫）</p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/184144?cid=19365" target="_blank">鳥取砂丘 \| 日本唯一のスリリングな砂滑り体験</a></p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/11463-osaka-bus-tour-tottori-sand-dunes-uratomi-coast-cruise-sand-museum-japan?cid=19365" target="_blank">【鳥取バス日帰りツアー】鳥取砂丘、浦富海岸クルーズ、砂の美術館、梨狩り体験｜特色ランチ付き（大阪発）</a></p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/262558?cid=19365" target="_blank">鳥取砂丘と有名な出雲大社を巡る2日間バスツアー（大阪発）</a></p>
  </li>
  <li>
    <p><a href="https://www.kkday.com/zh-tw/product/185589?cid=19365" target="_blank">新年参拝！出雲大社3時間滞在【広島発】</a></p>
  </li>
</ul>

<blockquote>
  <p><a href="https://www.kkday.com/zh-tw?cid=19365" target="_blank">この記事がお役に立ちましたら、私のプロモーションリンクを使ってKKdayの商品やツアーをご購入ください。収益の一部をいただき、今後も旅のコンテンツを作り続けます。ありがとうございます。</a></p>
</blockquote>

<h3 id="もっと旅行記">もっと旅行記</h3>

<ul>
  <li>
    <p><a href="https://blog.zhgchg.li/%E9%81%8A%E8%A8%98-2025-%E9%9F%93%E5%9C%8B%E9%87%9C%E5%B1%B1-8-%E5%A4%A9-7-%E5%A4%9C%E8%87%AA%E7%94%B1%E8%A1%8C-8ace34a1a3d8?source=collection_home_page----96927b78a281-----0-----------------------------------" target="_blank">[旅行記] 2025年 韓国釜山 8日間7泊の自由旅行</a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/九州自由行-福岡-長崎-熊本を巡る10日間の独り旅ガイド-d78e0b15a08a/">[旅行記] 2023年 九州 10日間の一人旅</a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/山陽地區自由行-廣島-岡山を巡る6日間の旅プラン-観光スポットと移動攻略-31b9b3a63abc/"><strong>[旅行記] 2023 山陽地域 広島・岡山 6日間自由旅行</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/z-度旅行遊記/名古屋一日快閃自由行-樂桃航空機票攻略と観光スポット紹介-7b8a0563c157/">[旅行記] 9/11 名古屋日帰り弾丸ツアー</a></p>
  </li>
  <li>
    <p>[旅行記] <a href="/posts/z-度旅行記/東京自由行-5日間の観光-グルメ-宿泊情報を徹底解説-9da2c51fa4f2/">2023 東京 5日間自由旅行</a></p>
  </li>
  <li>
    <p>[旅行記] <a href="/posts/z-度旅行遊記/京阪神自由行-8日間の京都-大阪-神戸旅行完全ガイド-食事-宿泊-交通情報を網羅-76d66c2e34af/">2023 京阪神 8日間自由旅行</a></p>
  </li>
</ul>

<p><em><a href="https://medium.com/ztravel/%E9%81%8A%E8%A8%98-2024-%E5%B1%B1%E9%99%B0%E5%9C%B0%E5%8D%80-%E9%97%9C%E8%A5%BF-%E5%B3%B6%E6%A0%B9%E9%B3%A5%E5%8F%96%E5%A7%AC%E8%B7%AF%E5%A4%A7%E9%98%AA-7-%E6%97%A5%E7%8D%A8%E6%97%85%E8%87%AA%E7%94%B1%E8%A1%8C-aacd5f5cacd1" target="_blank">投稿</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>により変換。</em></p>]]></content>
  </entry><entry>
    <title type="html">GitHub PagesでLinkTree風連結ページを無料高速構築｜完全カスタマイズ＆独自ドメイン対応</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/github-pages%E3%81%A7linktree%E9%A2%A8%E9%80%A3%E7%B5%90%E3%83%9A%E3%83%BC%E3%82%B8%E3%82%92%E7%84%A1%E6%96%99%E9%AB%98%E9%80%9F%E6%A7%8B%E7%AF%89-%E5%AE%8C%E5%85%A8%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-%E7%8B%AC%E8%87%AA%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E5%AF%BE%E5%BF%9C-70aeddb1fd9b/" rel="alternate" type="text/html" title="GitHub PagesでLinkTree風連結ページを無料高速構築｜完全カスタマイズ＆独自ドメイン対応" />
    <published>2024-10-27T13:36:34+08:00</published>
    <updated>2024-10-27T21:57:18+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/70aeddb1fd9b</id><summary type="html">GitHub Pagesを活用し、無料で高速に個人用LinkTree風連結ページを作成。カスタマイズ自由＆独自ドメイン対応で、自分だけのリンク集を簡単に実現します。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm ロボティック・プロセス・オートメーション" /><category term="リンクツリー" /><category term="githubページ" /><category term="自動化" /><category term="ルビー" /><category term="jekyll" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/70aeddb1fd9b/1*CbiCUtVY5CV4wRXBaZBoyw.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/github-pages%E3%81%A7linktree%E9%A2%A8%E9%80%A3%E7%B5%90%E3%83%9A%E3%83%BC%E3%82%B8%E3%82%92%E7%84%A1%E6%96%99%E9%AB%98%E9%80%9F%E6%A7%8B%E7%AF%89-%E5%AE%8C%E5%85%A8%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-%E7%8B%AC%E8%87%AA%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E5%AF%BE%E5%BF%9C-70aeddb1fd9b/"><![CDATA[<h3 id="linkyee--github-pages-を使って個人用-linktree-風リンクページを無料かつ迅速に作成する方法">linkyee — GitHub Pages を使って個人用 LinkTree 風リンクページを無料かつ迅速に作成する方法</h3>

<p>GitHub Pages を使って自分のリンクページを素早く作成、100%無料でカスタマイズ可能かつ独自ドメイン対応</p>

<h3 id="成果">成果</h3>

<p><img src="/assets/70aeddb1fd9b/1*EtG_srpR0i0BRE1dziNDXg.webp" alt="&lt;https://link.zhgchg.li&gt;" loading="lazy" decoding="async" width="1400" height="948" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijk0OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/70aeddb1fd9b/1*EtG_srpR0i0BRE1dziNDXg.png" /></p>

<p><a href="https://link.zhgchg.li" target="_blank">https://link.zhgchg.li</a></p>

<blockquote>
  <p><strong><em>私は成果をオープンソース化し、Template Repo（linkyee）としてパッケージ化しました。必要な方は直接 Fork してすぐにデプロイできます。</em></strong></p>
</blockquote>

<h3 id="linkyee--あなた専用のリンクページ">linkyee — あなた専用のリンクページ</h3>

<p><a href="https://github.com/ZhgChgLi/linkyee" target="_blank"><img src="https://repository-images.githubusercontent.com/877945203/b2d2ec07-9a56-400c-b24c-db0b180f7d3e" alt="" /></a></p>

<h4 id="利点">利点：</h4>

<ul>
  <li>
    <p>Github Pages に直接デプロイして安定かつ無料</p>
  </li>
  <li>
    <p>HTML のソースファイルを完全に管理でき、レイアウトやスタイルを自由に変更可能。広告や著作権表示の削除もできます。<em>(デフォルトのスタイルは私が GenAI ChatGPT を使って作成しました)</em></p>
  </li>
  <li>
    <p>カスタムドメインに対応</p>
  </li>
  <li>
    <p><strong>動的変数をサポート。例えば、デフォルトで設定した Medium のフォロワー数や Github リポジトリのスター数を自動で反映し、ページ上でフォロワー数を更新できます。</strong> 🚀🚀🚀</p>
  </li>
  <li>
    <p>ページの読み込みが高速</p>
  </li>
  <li>
    <p>以下の簡単な手順で設定とデプロイが完了します</p>
  </li>
</ul>

<h3 id="github-pages">Github Pages</h3>

<p>Github Pages は Github が提供する無料の静的ページホスティングサービスで、すべての Github Free アカウントは Public Repo であれば直接利用可能です。Private Repo の場合は、先に有料プランにアップグレードする必要があります。</p>

<h4 id="制限">制限</h4>

<ul>
  <li>
    <p><strong>静的ファイルリソースのみホスティング可能：</strong> HTML、CSS、JavaScript、フォントファイル、画像ファイル、PDF、音声ファイル、テキストファイルなど</p>
  </li>
  <li>
    <p><strong>サイト（リポジトリ）サイズの上限：</strong> 1 GB これはソフトリミットと考えられます。私の Github Pages Jekyll リポジトリはすでにほぼ5 GBあります。</p>
  </li>
  <li>
    <p><strong>デプロイ時間の最大：</strong> 10分</p>
  </li>
  <li>
    <p><strong>1時間あたりの最大デプロイ回数：</strong> 10回（ソフトリミット）</p>
  </li>
  <li>
    <p><strong>月間トラフィック制限：</strong> 100 GB（ソフトリミット）</p>
  </li>
  <li>
    <p>リクエストが多すぎる場合、HTTP 429が返される可能性があります。</p>
  </li>
</ul>

<h4 id="その他の-github-pages-活用記事">その他の Github Pages 活用記事</h4>

<ul>
  <li>
    <p><a href="/posts/zrealm-dev/mediumからgithub-pagesへ無痛転送-jekyllとchirpyで簡単サイト構築-a0c08d579ab1/">私が Github Pages でデプロイした Jekyll ブログ</a> ➡️ <a href="https://zhgchg.li/" target="_blank"><strong>ZhgChgLi</strong></a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/mediumからgithub-pagesへ無痛転送-jekyllとchirpyで簡単サイト構築-a0c08d579ab1/">MediumからGithub Pagesへのスムーズな移行</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-dev/github-pages-自訂網域設定で独自urlを実現-簡単手順ガイド-483af5d93297/"><strong>Github Pages カスタムドメイン設定ガイド</strong></a></p>
  </li>
</ul>

<h3 id="はじめに--github-pages-へのデプロイ">はじめに — GitHub Pages へのデプロイ</h3>

<h4 id="ステップ-1-linkyee-テンプレートリポジトリの右上にあるuse-this-templateボタンをクリックしcreate-a-new-repositoryを選択">ステップ 1. linkyee テンプレートリポジトリの右上にある「Use this template」ボタンをクリックし、「Create a new repository」を選択：</h4>

<p><img src="/assets/70aeddb1fd9b/1*G6pU845OnIyEdl-Os0EnwQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="993" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk5MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/70aeddb1fd9b/1*G6pU845OnIyEdl-Os0EnwQ.png" /></p>

<h4 id="ステップ-2-include-all-branchesにチェックを入れ希望する-github-pages-リポジトリ名を入力し完了したらcreate-repositoryをクリックします">ステップ 2. 「Include all branches」にチェックを入れ、希望する GitHub Pages リポジトリ名を入力し、完了したら「Create repository」をクリックします：</h4>

<p><img src="/assets/70aeddb1fd9b/1*PN9zygdxqJmFtUz9Pq35cQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="993" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk5MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/70aeddb1fd9b/1*PN9zygdxqJmFtUz9Pq35cQ.png" /></p>

<blockquote>
  <p><em>GitHub Pages のリポジトリ名がアクセスURLになります。</em></p>
</blockquote>

<blockquote>
  <p><em>もしリポジトリ名を <code class="language-plaintext highlighter-rouge">your-username.github.io</code> にすると、これがあなたの GitHub Pages サイトの直接アクセスURLになります。</em></p>
</blockquote>

<blockquote>
  <p><em>もし既に <code class="language-plaintext highlighter-rouge">your-username.github.io</code> リポジトリをお持ちの場合、GitHub Pages のURLは <code class="language-plaintext highlighter-rouge">your-username.github.io/Repo-Name</code> となります。</em></p>
</blockquote>

<h4 id="fork-の完了を待ちます初回作成時にデプロイエラーが発生することがありますがこれは-fork-したリポジトリの権限の問題によるものです次に手順に従って調整を行います">Fork の完了を待ちます。初回作成時にデプロイエラーが発生することがありますが、これは Fork したリポジトリの権限の問題によるものです。次に手順に従って調整を行います。</h4>

<p><img src="/assets/70aeddb1fd9b/1*EYXix1zABfKXboAxkn_-yw.webp" alt="" loading="lazy" decoding="async" width="374" height="74" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNzQiIGhlaWdodD0iNzQiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/70aeddb1fd9b/1*EYXix1zABfKXboAxkn_-yw.png" /></p>

<h4 id="ステップ-4-settings---actions---general-に移動し以下のオプションを選択してください">ステップ 4. Settings -&gt; Actions -&gt; General に移動し、以下のオプションを選択してください：</h4>

<p><img src="/assets/70aeddb1fd9b/1*5c4TZm0ZjolIPPalwEbJMA.webp" alt="" loading="lazy" decoding="async" width="1200" height="993" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk5MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/70aeddb1fd9b/1*5c4TZm0ZjolIPPalwEbJMA.png" /></p>

<ul>
  <li>
    <p>Actions の権限：すべてのアクションと再利用可能なワークフローを許可する</p>
  </li>
  <li>
    <p>ワークフローの権限：読み取りおよび書き込み権限</p>
  </li>
</ul>

<p><strong>選択が完了したら、Save ボタンをクリックして変更を保存してください。</strong></p>

<h4 id="ステップ-5-settings---pages-に移動しgithub-pages-のブランチ設定がgh-pagesになっていることを確認します">ステップ 5. Settings -&gt; Pages に移動し、GitHub Pages のブランチ設定が「gh-pages」になっていることを確認します：</h4>

<p><img src="/assets/70aeddb1fd9b/1*2mmeneQOLEuhRqZIovSh9A.webp" alt="" loading="lazy" decoding="async" width="1400" height="1159" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjExNTkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/70aeddb1fd9b/1*2mmeneQOLEuhRqZIovSh9A.png" /></p>

<blockquote>
  <p><em>「Your site is live at: XXXX」というメッセージは、あなたの GitHub Pages 公開アクセスURLです。</em></p>
</blockquote>

<h4 id="ステップ-6-settings---actions-に移動し最初のデプロイ完了を待つ">ステップ 6. Settings -&gt; Actions に移動し、最初のデプロイ完了を待つ：</h4>

<p><img src="/assets/70aeddb1fd9b/1*mFQmtcTZr-OjBhqtHwebEw.webp" alt="" loading="lazy" decoding="async" width="1400" height="1159" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjExNTkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/70aeddb1fd9b/1*mFQmtcTZr-OjBhqtHwebEw.png" /></p>

<h4 id="ステップ-7-github-pages-の-url-にアクセスしてfork-が成功したか確認する">ステップ 7. GitHub Pages の URL にアクセスして、Fork が成功したか確認する：</h4>

<p><img src="/assets/70aeddb1fd9b/1*1vaJpnwjZtsWEjBvKcGjVw.webp" alt="" loading="lazy" decoding="async" width="1200" height="993" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk5MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/70aeddb1fd9b/1*1vaJpnwjZtsWEjBvKcGjVw.png" /></p>

<blockquote>
  <p>おめでとうございます！デプロイが成功しました。これで設定ファイルを編集して、ご自身の情報に置き換えることができます。🎉🎉🎉</p>
</blockquote>

<h3 id="設定">設定</h3>

<h4 id="設定ファイル">設定ファイル</h4>

<p>ルートディレクトリにある config.yml ファイルを編集します。</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># サイト設定  </span>

<span class="c1"># テーマ名、対応するディレクトリ：./theme/xxxx  </span>
<span class="na">theme</span><span class="pi">:</span> <span class="s">default</span>  

<span class="c1"># HTML言語設定  </span>
<span class="na">lang</span><span class="pi">:</span> <span class="s2">"</span><span class="s">en"</span>  

<span class="c1"># プラグイン（./plugins/PLUGIN_NAME に実装）  </span>
<span class="c1"># 下記設定で {{ vars.PLUGIN_NAME }} を使用  </span>

<span class="c1"># プラグインの出力結果は下記で利用可能、例：{{vars.MediumFollowersCountPlugin}}  </span>
<span class="na">plugins</span><span class="pi">:</span>  
  <span class="c1"># Mediumのフォロワー数を自動取得  </span>
  <span class="pi">-</span> <span class="na">MediumFollowersCountPlugin</span><span class="pi">:</span>  
      <span class="na">username</span><span class="pi">:</span> <span class="s">zhgchgli</span>  
  <span class="c1"># GitHubリポジトリのスター数を自動取得  </span>
  <span class="pi">-</span> <span class="na">GithubRepoStarsCountPlugin</span><span class="pi">:</span>  
      <span class="pi">-</span> <span class="s">ZhgChgLi/ZMarkupParser</span>  
      <span class="pi">-</span> <span class="s">ZhgChgLi/ZReviewTender</span>  
      <span class="pi">-</span> <span class="s">ZhgChgLi/ZMediumToMarkdown</span>  
      <span class="pi">-</span> <span class="s">ZhgChgLi/linkyee</span>  

<span class="c1"># Google Analytics トラッキングID  </span>
<span class="na">google_analytics_id</span><span class="pi">:</span>  

<span class="c1"># HTMLタイトル  </span>
<span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">のリンク集"</span>  

<span class="c1"># アバター画像パス  </span>
<span class="na">avatar</span><span class="pi">:</span> <span class="s2">"</span><span class="s">./images/profile.jpeg"</span>  

<span class="c1"># 名前表示テキスト  </span>
<span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">@zhgchgli"</span>  

<span class="c1"># キャッチフレーズテキスト  </span>
<span class="na">tagline</span><span class="pi">:</span> <span class="pi">&gt;-</span>  
    <span class="s">台湾出身のiOS、ウェブ、自動化開発者。共有、旅行、執筆を愛しています。  </span>

<span class="c1"># リンクリスト  </span>
<span class="c1"># icon：Font Awesome アイコン使用 (https://fontawesome.com/search?o=r&amp;m=free)  </span>
<span class="c1"># text：リンクに表示されるテキスト  </span>
<span class="c1"># title：リンクのタイトル  </span>
<span class="c1"># url：リンク先URL  </span>
<span class="c1"># alt：代替テキスト（アクセシビリティ用）  </span>
<span class="c1"># target：`_blank` 新しいタブで開く、`_self` 同一ページで開く  </span>
<span class="na">links</span><span class="pi">:</span>  
  <span class="pi">-</span> <span class="na">link</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-medium"</span>  
      <span class="na">text</span><span class="pi">:</span> <span class="s2">"</span><span class="s">技術ブログ</span><span class="nv"> </span><span class="s">&lt;span</span><span class="nv"> </span><span class="s">class='link-button-text'&gt;({{vars.MediumFollowersCountPlugin}}</span><span class="nv"> </span><span class="s">フォロワー)&lt;/span&gt;"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://blog.zhgchg.li"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の技術ブログ"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の技術ブログ"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">link</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-medium"</span>  
      <span class="na">text</span><span class="pi">:</span> <span class="s2">"</span><span class="s">旅行日記</span><span class="nv"> </span><span class="s">&lt;span</span><span class="nv"> </span><span class="s">class='link-button-text'&gt;({{vars.MediumFollowersCountPlugin}}</span><span class="nv"> </span><span class="s">フォロワー)&lt;/span&gt;"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://medium.com/ztravel"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の旅行日記"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の旅行日記"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">link</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-solid</span><span class="nv"> </span><span class="s">fa-rss"</span>  
      <span class="na">text</span><span class="pi">:</span> <span class="s2">"</span><span class="s">個人サイト"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://zhgchg.li/"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">のサイト"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">のサイト"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">link</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-swift"</span>  
      <span class="na">text</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZMarkupParser</span><span class="nv"> </span><span class="s">&lt;span</span><span class="nv"> </span><span class="s">class='link-button-text'&gt;({{vars.GithubRepoStarsCountPlugin['ZhgChgLi/ZMarkupParser']}}</span><span class="nv"> </span><span class="s">スター)&lt;/span&gt;"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://github.com/ZhgChgLi/ZMarkupParser"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZMarkupParser</span><span class="nv"> </span><span class="s">はHTML文字列をカスタムスタイルのNSAttributedStringに変換する純Swiftライブラリです。"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZMarkupParser</span><span class="nv"> </span><span class="s">はHTML文字列をカスタムスタイルのNSAttributedStringに変換する純Swiftライブラリです。"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">link</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-app-store-ios"</span>  
      <span class="na">text</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZReviewTender</span><span class="nv"> </span><span class="s">&lt;span</span><span class="nv"> </span><span class="s">class='link-button-text'&gt;({{vars.GithubRepoStarsCountPlugin['ZhgChgLi/ZReviewTender']}}</span><span class="nv"> </span><span class="s">スター)&lt;/span&gt;"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://github.com/ZhgChgLi/ZReviewTender"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZReviewTender</span><span class="nv"> </span><span class="s">はApp</span><span class="nv"> </span><span class="s">StoreとGoogle</span><span class="nv"> </span><span class="s">Play</span><span class="nv"> </span><span class="s">Consoleからアプリレビューを取得しワークフローに統合するツールです。"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZReviewTender</span><span class="nv"> </span><span class="s">はApp</span><span class="nv"> </span><span class="s">StoreとGoogle</span><span class="nv"> </span><span class="s">Play</span><span class="nv"> </span><span class="s">Consoleからアプリレビューを取得しワークフローに統合するツールです。"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">link</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-markdown"</span>  
      <span class="na">text</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZMediumToMarkdown</span><span class="nv"> </span><span class="s">&lt;span</span><span class="nv"> </span><span class="s">class='link-button-text'&gt;({{vars.GithubRepoStarsCountPlugin['ZhgChgLi/ZMediumToMarkdown']}}</span><span class="nv"> </span><span class="s">スター)&lt;/span&gt;"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://github.com/ZhgChgLi/ZMediumToMarkdown"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZMediumToMarkdown</span><span class="nv"> </span><span class="s">はMedium記事を簡単にダウンロードしてMarkdown形式に変換する強力なツールです。"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZMediumToMarkdown</span><span class="nv"> </span><span class="s">はMedium記事を簡単にダウンロードしてMarkdown形式に変換する強力なツールです。"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">link</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-github"</span>  
      <span class="na">text</span><span class="pi">:</span> <span class="s2">"</span><span class="s">linkyee</span><span class="nv"> </span><span class="s">&lt;span</span><span class="nv"> </span><span class="s">class='link-button-text'&gt;({{vars.GithubRepoStarsCountPlugin['ZhgChgLi/linkyee']}}</span><span class="nv"> </span><span class="s">スター)&lt;/span&gt;"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://github.com/ZhgChgLi/linkyee"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">linkyee</span><span class="nv"> </span><span class="s">は完全カスタマイズ可能でオープンソースのLinkTree代替で、GitHub</span><span class="nv"> </span><span class="s">Pagesに直接デプロイ可能です。"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">linkyee</span><span class="nv"> </span><span class="s">は完全カスタマイズ可能でオープンソースのLinkTree代替で、GitHub</span><span class="nv"> </span><span class="s">Pagesに直接デプロイ可能です。"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  

<span class="c1"># ソーシャルメディアリンクリスト  </span>
<span class="c1"># icon：Font Awesome アイコン使用 (https://fontawesome.com/search?o=r&amp;m=free)  </span>
<span class="c1"># title：リンクのタイトル  </span>
<span class="c1"># url：ソーシャルメディアのURL  </span>
<span class="c1"># alt：代替テキスト（アクセシビリティ用）  </span>
<span class="c1"># target：`_blank` 新しいタブで開く、`_self` 同一ページで開く  </span>
<span class="na">socials</span><span class="pi">:</span>  
  <span class="pi">-</span> <span class="na">social</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-medium"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://blog.zhgchg.li"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の</span><span class="nv"> </span><span class="s">Medium"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の</span><span class="nv"> </span><span class="s">Medium"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">social</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-github"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://github.com/ZhgChgLi"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の</span><span class="nv"> </span><span class="s">GitHub"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の</span><span class="nv"> </span><span class="s">GitHub"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">social</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-twitter"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://twitter.com/zhgchgli"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の</span><span class="nv"> </span><span class="s">Twitter"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の</span><span class="nv"> </span><span class="s">Twitter"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">social</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-linkedin"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://www.linkedin.com/in/zhgchgli/"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の</span><span class="nv"> </span><span class="s">LinkedIn"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の</span><span class="nv"> </span><span class="s">LinkedIn"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">social</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-brands</span><span class="nv"> </span><span class="s">fa-instagram"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://www.instagram.com/zhgchgli/"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Instagram"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ZhgChgLi</span><span class="nv"> </span><span class="s">の</span><span class="nv"> </span><span class="s">Instagram"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  
  <span class="pi">-</span> <span class="na">social</span><span class="pi">:</span>  
      <span class="na">icon</span><span class="pi">:</span> <span class="s2">"</span><span class="s">fa-solid</span><span class="nv"> </span><span class="s">fa-envelope"</span>  
      <span class="na">url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">zhgchgli@gmail.com"</span>  
      <span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Email:</span><span class="nv"> </span><span class="s">zhgchgli@gmail.com"</span>  
      <span class="na">alt</span><span class="pi">:</span> <span class="s2">"</span><span class="s">zhgchgli@gmail.com"</span>  
      <span class="na">target</span><span class="pi">:</span> <span class="s2">"</span><span class="s">_blank"</span>  

<span class="c1"># フッターテキスト  </span>
<span class="na">footer</span><span class="pi">:</span> <span class="pi">&gt;</span>  
    <span class="s">私のサイトへようこそ！MediumやGitHubで最新情報をフォローし、InstagramやLinkedInでつながりましょう。  </span>

<span class="c1"># フッター著作権表示  </span>
<span class="c1"># Linkyeeは100%無料のオープンソースプロジェクトです—著作権表示は自由に変更可能です。:)  </span>
<span class="na">copyright</span><span class="pi">:</span> <span class="pi">&gt;</span>  
  <span class="s">© 2024 &lt;a href="https://zhgchg.li" target="_blank"&gt;ZhgChgLi&lt;/a&gt;。&lt;a href="https://github.com/ZhgChgLi/linkyee" target="_blank"&gt;linkyee&lt;/a&gt; による技術支援。  </span>
</code></pre></div></div>

<blockquote>
  <p><strong><em>ご注意：ファイルを変更するたびに、GitHub Actions が自動でビルドし、ページのビルドとデプロイが完了するまでお待ちください。</em></strong></p>
</blockquote>

<p><img src="/assets/70aeddb1fd9b/1*56qGAyuECrqDJQMoKbPiOw.webp" alt="" loading="lazy" decoding="async" width="1200" height="999" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk5OSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/70aeddb1fd9b/1*56qGAyuECrqDJQMoKbPiOw.png" /></p>

<blockquote>
  <p><strong><em>ページをリロードして変更を反映してください。🚀</em></strong></p>
</blockquote>

<p><img src="/assets/70aeddb1fd9b/1*CbiCUtVY5CV4wRXBaZBoyw.webp" alt="" loading="lazy" decoding="async" width="1200" height="809" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwOSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/70aeddb1fd9b/1*CbiCUtVY5CV4wRXBaZBoyw.jpeg" /></p>

<p>成功！！</p>

<h4 id="カスタムスタイルの設定とデフォルトテーマの変更">カスタムスタイルの設定とデフォルトテーマの変更</h4>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">./themes/default/index.html</code></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">./themes/default/styles.css</code></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">./themes/default/scripts.js</code></p>
  </li>
</ul>

<h4 id="新しいテーマの作成">新しいテーマの作成</h4>

<ul>
  <li>
    <p>./themes/ <code class="language-plaintext highlighter-rouge">YOUR_THEME</code></p>
  </li>
  <li>
    <p>config.yml ファイルで <code class="language-plaintext highlighter-rouge">theme:YOUR_THEME</code> に更新してください。</p>
  </li>
</ul>

<p><strong>その通りです。ChatGPTのようなGenAIツールを使って、カスタムリンクページの作成を手助けすることができます！（デフォルトのスタイルも私がChatGPTで作成しました）</strong></p>

<h4 id="自動再デプロイ">自動再デプロイ</h4>

<p>デフォルトでは、プロジェクトは毎日自動的に再デプロイされ、プラグインの動的変数値が更新されます。<a href="https://github.com/ZhgChgLi/linkyee/blob/main/.github/workflows/build.yml" target="_blank">Github Action — Automatic build (.github/workflows/build.yml)</a> で cron 設定を調整できます：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">schedule</span><span class="pi">:</span>
 <span class="pi">-</span> <span class="na">cron</span><span class="pi">:</span> <span class="s1">'</span><span class="s">0</span><span class="nv"> </span><span class="s">0</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">*</span><span class="nv"> </span><span class="s">*'</span> <span class="c1"># 毎日深夜00:00（UTC）に実行</span>
</code></pre></div></div>

<p>定期的な再デプロイが不要な場合は、<code class="language-plaintext highlighter-rouge">schedule</code> ブロックをそのまま削除してください。</p>

<h3 id="カスタムドメイン-️️️">カスタムドメイン ❤️❤️❤️</h3>

<p>カスタムの GitHub Pages ドメインを設定できます。<strong>例えば私のはこちら： <a href="https://link.zhgchg.li" target="_blank">https://link.zhgchg.li</a> 。</strong></p>

<p>以前の記事「<a href="/posts/zrealm-dev/github-pages-自訂網域設定で独自urlを実現-簡単手順ガイド-483af5d93297/"><strong>Github Pages カスタムドメイン設定ガイド</strong></a>」では、購入からドメインの紐付けまでをステップごとに説明しています。また、<a href="https://namecheap.pxf.io/P0jdZQ" target="_blank"><strong>私の Namecheap 紹介リンクからドメインを購入</strong></a>すると、私に一部の報酬が入ります。これにより、引き続きオープンソースプロジェクトに貢献できます。</p>

<h3 id="コーヒーをおごってください-️️️">コーヒーをおごってください ❤️❤️❤️</h3>

<p><img src="/assets/70aeddb1fd9b/1*QCQqlZr6doDP-cszzpaSpw.webp" alt="&lt;https://www.paypal.com/ncp/payment/CMALMPT8UUTY2&gt;" loading="lazy" decoding="async" width="1090" height="306" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDkwIiBoZWlnaHQ9IjMwNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/70aeddb1fd9b/1*QCQqlZr6doDP-cszzpaSpw.png" /></p>

<p><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank">https://www.paypal.com/ncp/payment/CMALMPT8UUTY2</a></p>

<p>このプロジェクトが役に立った場合は、<a href="https://github.com/ZhgChgLi/linkyee" target="_blank">Star Repo、友達におすすめする</a> か、<strong><a href="https://www.paypal.com/ncp/payment/CMALMPT8UUTY2" target="_blank">コーヒーを一杯ご支援ください。ご支援ありがとうございます！</a></strong> をご検討ください。</p>

<p>Issueの提出やPull Requestでの修正・貢献を歓迎します。:)</p>

<p><em><a href="https://medium.com/zrealm-robotic-process-automation/linkyee-%E4%BD%BF%E7%94%A8-github-pages-%E5%BF%AB%E9%80%9F%E5%85%8D%E8%B2%BB%E5%BB%BA%E7%AB%8B%E5%80%8B%E4%BA%BA%E9%A1%9E-linktree-%E9%80%A3%E7%B5%90%E9%A0%81%E9%9D%A2-70aeddb1fd9b" target="_blank">Post</a> Mediumから変換 by <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>.</em></p>]]></content>
  </entry><entry>
    <title type="html">GA4自動数値通知ロボット：無料で作る3ステップ｜Google Apps ScriptとTelegram Bot連携</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/ga4%E8%87%AA%E5%8B%95%E6%95%B0%E5%80%A4%E9%80%9A%E7%9F%A5%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88-%E7%84%A1%E6%96%99%E3%81%A7%E4%BD%9C%E3%82%8B3%E3%82%B9%E3%83%86%E3%83%83%E3%83%97-google-apps-script%E3%81%A8telegram-bot%E9%80%A3%E6%90%BA-1e85b8df2348/" rel="alternate" type="text/html" title="GA4自動数値通知ロボット：無料で作る3ステップ｜Google Apps ScriptとTelegram Bot連携" />
    <published>2024-10-20T16:19:52+08:00</published>
    <updated>2024-10-20T16:19:52+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/1e85b8df2348</id><summary type="html">GA4のデータ通知を自動化したい方必見。Google Apps ScriptでRPAを実装し、Telegram Botと連携する3ステップで無料の通知ロボットを構築。手間なくリアルタイムに重要指標を受け取れます。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm ロボティック・プロセス・オートメーション" /><category term="自動化" /><category term="google-apps-script" /><category term="テレグラム" /><category term="googleアナリティクス" /><category term="rpaソリューション" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/1e85b8df2348/1*La0AKKSrGNP9EZUV-vrONQ.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/ga4%E8%87%AA%E5%8B%95%E6%95%B0%E5%80%A4%E9%80%9A%E7%9F%A5%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88-%E7%84%A1%E6%96%99%E3%81%A7%E4%BD%9C%E3%82%8B3%E3%82%B9%E3%83%86%E3%83%83%E3%83%97-google-apps-script%E3%81%A8telegram-bot%E9%80%A3%E6%90%BA-1e85b8df2348/"><![CDATA[<h3 id="簡単な3ステップ--無料でga4自動データ通知ボットを作成する">簡単な3ステップ — 無料でGA4自動データ通知ボットを作成する</h3>

<p>Google Apps Script を使って RPA を実現し、GA4 と Telegram Bot を連携したデータ通知ロボットを自作する</p>

<p><img src="/assets/1e85b8df2348/1*La0AKKSrGNP9EZUV-vrONQ.webp" alt="Photo by BoliviaInteligente" loading="lazy" decoding="async" width="1200" height="750" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijc1MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/1e85b8df2348/1*La0AKKSrGNP9EZUV-vrONQ.jpeg" /></p>

<p>Photo by <a href="https://unsplash.com/@boliviainteligente?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash" target="_blank">BoliviaInteligente</a></p>

<h3 id="はじめに">はじめに</h3>

<p>大体2020年頃から、自分の手元にあるツールを使ってRPAを試行錯誤してきました。最初は個人のルーティン作業の自動化だけでしたが、後に仕事でもより大規模な組織に関わるようになり、チーム間の連携や人に依存する作業、さらには繰り返しの作業に頻繁に直面するようになりました。そこで初めて、RPA自動化の効果を実感しました。</p>

<p>例えば、ある繰り返し作業が毎月10回発生し、1回あたり30分かかるとします。これに60人が関わる場合、年間でチーム全体で3,600時間を費やしています。もし100時間を投資して自動化を開発できれば、その後に解放された時間をより価値のある仕事に充てることができます。実質的には3,600時間の無駄な工数＋3,600時間のより価値ある成果ということになります。</p>

<h4 id="詳細は以前の記事をご参照ください"><strong>詳細は以前の記事をご参照ください：</strong></h4>

<ul>
  <li>
    <p><a href="/posts/pinkoiエンジニアリング/pinkoi-tech-talk-高効率エンジニアチームの秘密を徹底解説-11f6c8568154/">2021 Pinkoi Tech Career Talk — 高効率エンジニアチームの秘密</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティックプロセスオートメーション/google-apps-scriptで毎日データ報告をrpa自動化-効率化と正確性向上の秘訣-f6713ba3fee3/">Google Apps Scriptを使って毎日のデータレポートRPA自動化を実現する</a></p>
  </li>
</ul>

<h4 id="その他に行ったrpa">その他に行ったRPA：</h4>

<ul>
  <li>
    <p>[GMail to Slack] <a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-scriptでgmailをslackに自動転送-フィルター連携で効率化-d414bdbdb8c9/">Google Apps Script を使って Gmail メールを Slack に転送する方法</a></p>
  </li>
  <li>
    <p>[Google Form x Google Sheet xSlack] <a href="https://medium.com/zrealm-robotic-process-automation/slack-%E6%89%93%E9%80%A0%E5%85%A8%E8%87%AA%E5%8B%95-wfh-%E5%93%A1%E5%B7%A5%E5%81%A5%E5%BA%B7%E7%8B%80%E6%B3%81%E5%9B%9E%E5%A0%B1%E7%B3%BB%E7%B5%B1-d61062833c1a?source=collection_home---6------9-----------------------" target="_blank">Slackで作る完全自動WFH社員健康状況報告システム</a></p>
  </li>
  <li>
    <p>[Big Query x Slack ] <a href="https://medium.com/zrealm-robotic-process-automation/crashlytics-big-query-%E6%89%93%E9%80%A0%E6%9B%B4%E5%8D%B3%E6%99%82%E4%BE%BF%E5%88%A9%E7%9A%84-crash-%E8%BF%BD%E8%B9%A4%E5%B7%A5%E5%85%B7-e77b80cc6f89?source=collection_home---6------7-----------------------" target="_blank">Crashlytics + Big Query でよりリアルタイムで便利なクラッシュ追跡ツールを作る</a></p>
  </li>
  <li>
    <p>[Google Analytics x Slack] <a href="https://medium.com/zrealm-robotic-process-automation/crashlytics-google-analytics-%E8%87%AA%E5%8B%95%E6%9F%A5%E8%A9%A2-app-crash-free-users-rate-793cb8f89b72?source=collection_home---6------6-----------------------" target="_blank">Crashlytics + Google Analytics 自動で App のクラッシュフリー ユーザー率を照会</a></p>
  </li>
  <li>
    <p>[Github Webhook x Line Notify] <a href="https://medium.com/zrealm-robotic-process-automation/%E4%BD%BF%E7%94%A8-google-apps-script-%E4%B8%89%E6%AD%A5%E9%A9%9F%E5%85%8D%E8%B2%BB%E5%BB%BA%E7%AB%8B-github-repo-star-notifier-382218e15697?source=collection_home---6------5-----------------------" target="_blank">Google Apps Scriptを使って3ステップで無料でGithubリポジトリのスター通知を作成する方法</a></p>
  </li>
  <li>
    <p>[Slack x OpenAI (ChatGTP)] <a href="https://medium.com/zrealm-robotic-process-automation/slack-chatgpt-integration-bd94cc88f9c9?source=collection_home---6------4-----------------------" target="_blank">Slack &amp; ChatGPT インテグレーション</a></p>
  </li>
  <li>
    <p>[Google Analytics x Google Sheet] <a href="https://medium.com/zrealm-robotic-process-automation/%E4%BD%BF%E7%94%A8-google-apps-script-%E5%AF%A6%E7%8F%BE-google-%E6%9C%8D%E5%8B%99-rpa-%E8%87%AA%E5%8B%95%E5%8C%96-f6713ba3fee3?source=collection_home---6------3-----------------------" target="_blank">Google Apps Scriptを使った毎日データレポートのRPA自動化</a></p>
  </li>
  <li>
    <p>[iOS Shortcut x Line x Reminders] <a href="https://medium.com/zrealm-robotic-process-automation/ios-%E6%8D%B7%E5%BE%91%E8%87%AA%E5%8B%95%E5%8C%96%E6%87%89%E7%94%A8%E5%A0%B4%E6%99%AF-%E8%87%AA%E5%8B%95%E8%BD%89%E7%99%BC%E7%B0%A1%E8%A8%8A%E8%88%87%E8%87%AA%E5%8B%95%E5%BB%BA%E7%AB%8B%E6%8F%90%E9%86%92%E5%BE%85%E8%BE%A6%E4%BA%8B%E9%A0%85-309d0302877b?source=collection_home---6------2-----------------------" target="_blank">iOSショートカット自動化の活用例 — SMS自動転送とリマインダー自動作成</a></p>
  </li>
  <li>
    <p>[Apple Store API x Google Play Console API x Github Action] <a href="https://medium.com/zrealm-robotic-process-automation/quick-start-github-action-x-zreviewtender-%E5%85%8D%E8%B2%BB%E5%BF%AB%E9%80%9F%E9%83%A8%E7%BD%B2%E4%BD%A0%E7%9A%84-app-%E5%95%86%E5%9F%8E%E8%A9%95%E5%83%B9%E7%9B%A3%E6%8E%A7%E6%A9%9F%E5%99%A8%E4%BA%BA-0095528cf875?source=collection_home---6------1-----------------------" target="_blank">Github Action x ZReviewTender 無料で素早くあなたのアプリストア評価監視ロボットをデプロイ</a></p>
  </li>
  <li>
    <p>[Telegram Bot] <a href="https://medium.com/zrealm-robotic-process-automation/10-%E5%88%86%E9%90%98%E5%BF%AB%E9%80%9F%E7%A7%BB%E8%BD%89-line-notify-%E5%88%B0-telegram-bot-%E9%80%9A%E7%9F%A5-6922e90ba90c?source=collection_home---6------0-----------------------" target="_blank">10分で簡単にLine NotifyからTelegram Bot通知へ移行する方法</a></p>
  </li>
  <li>
    <p>[Medium to Jekyllrb] <a href="/posts/zrealm-dev/mediumからgithub-pagesへ無痛転送-jekyllとchirpyで簡単サイト構築-a0c08d579ab1/">Mediumから自分のサーバーへ無痛で移行する方法</a></p>
  </li>
</ul>

<p>バックエンドのデータを見ると、以前多くの記事が ChatGPT やさまざまな GenAI サービスに収録されており、エンジニア以外の方でも RPA を使って問題を解決したいと思っている方々の助けになっています。そこで、今後も自分の生活や仕事で出会った RPA のシナリオと解決策を皆さんと共有していきます — <a href="/posts/zrealm-ロボティック-プロセス-オートメーション/google-apps-scriptでgmailをslackに自動転送-フィルター連携で効率化-d414bdbdb8c9/">ZRealm Robotic Process Automation</a> 。</p>

<h4 id="お知らせタイム">お知らせタイム</h4>

<p>もしあなたやチームが自動化ツールやワークフロー連携を必要としている場合、Slackアプリ開発、Notion、Asana、Google Sheets、Google Forms、GAデータなど、あらゆる連携のご要望に対応します。ぜひ<a href="https://zhgchg.li/contact/" target="_blank"><strong>開発のご相談</strong></a>ください。</p>

<h3 id="本記事の-google-analytics-4-x-telegram-bot">本記事の Google Analytics 4 x Telegram Bot</h3>

<p>今回紹介する連携シナリオは、前回の記事「<a href="https://medium.com/zrealm-robotic-process-automation/10-%E5%88%86%E9%90%98%E5%BF%AB%E9%80%9F%E7%A7%BB%E8%BD%89-line-notify-%E5%88%B0-telegram-bot-%E9%80%9A%E7%9F%A5-6922e90ba90c?source=collection_home---6------0-----------------------" target="_blank">10 分で簡単に Line Notify から Telegram Bot 通知へ移行</a>」の続きで、私の Medium バックアップサイト「<a href="https://zhgchg.li/" target="_blank">zhgchg.li</a>」の GA4 ウェブサイトデータをずっと見ていなかったので、毎日過去7日間のサイトデータを指定の Telegram チャンネルに送信する通知ボットを作ろうと思いました。</p>

<p>本記事は小品ですが、完全な自動化データレポートを作成したい場合は、以前の記事「 <a href="https://medium.com/zrealm-robotic-process-automation/%E4%BD%BF%E7%94%A8-google-apps-script-%E5%AF%A6%E7%8F%BE-google-%E6%9C%8D%E5%8B%99-rpa-%E8%87%AA%E5%8B%95%E5%8C%96-f6713ba3fee3?source=collection_home---6------3-----------------------" target="_blank">使用 Google Apps Script 實現每日數據報表 RPA 自動化</a> 」を参照してください。また、以前に GA4 で App Crash-free rate を取得した例もあり、こちらの記事「 <a href="https://medium.com/zrealm-robotic-process-automation/crashlytics-google-analytics-%E8%87%AA%E5%8B%95%E6%9F%A5%E8%A9%A2-app-crash-free-users-rate-793cb8f89b72?source=collection_home---6------6-----------------------" target="_blank">Crashlytics + Google Analytics 自動查詢 App Crash-Free Users Rate</a> 」も参考にしてください。</p>

<ul>
  <li>
    <p>Google Apps Script の無料制限、詳細な使い方、デプロイ、機能紹介については本記事では詳しく解説しません。詳しくは<a href="https://medium.com/zrealm-robotic-process-automation/%E4%BD%BF%E7%94%A8-google-apps-script-%E5%AF%A6%E7%8F%BE-google-%E6%9C%8D%E5%8B%99-rpa-%E8%87%AA%E5%8B%95%E5%8C%96-f6713ba3fee3?source=collection_home---6------3-----------------------" target="_blank">以前の記事</a>をご覧ください。</p>
  </li>
  <li>
    <p>Telegram Bot の作成や使い方については、本記事では詳しく解説しません。詳しくは<a href="https://medium.com/zrealm-robotic-process-automation/10-%E5%88%86%E9%90%98%E5%BF%AB%E9%80%9F%E7%A7%BB%E8%BD%89-line-notify-%E5%88%B0-telegram-bot-%E9%80%9A%E7%9F%A5-6922e90ba90c?source=collection_home---6------0-----------------------" target="_blank">以前の記事</a>をご覧ください。</p>
  </li>
</ul>

<h4 id="成果">成果</h4>

<p><img src="/assets/1e85b8df2348/1*J7QdgrJRNzVFQJfW5UBBFA.webp" alt="" loading="lazy" decoding="async" width="555" height="460" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTUiIGhlaWdodD0iNDYwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/1e85b8df2348/1*J7QdgrJRNzVFQJfW5UBBFA.png" /></p>

<p>まず最終結果を紹介します。Google Apps Script は毎日12時から13時の間に自動で取得したい Google Analytics 4 のサイトデータを取得し、メッセージにまとめて Telegram Bot を通じて私の Telegram チャンネルに送信します。これにより、過去7日間のサイトデータを素早く確認できます。</p>

<p><strong>私が観測したいデータは：</strong></p>

<ul>
  <li>
    <p>直近7日間の <code class="language-plaintext highlighter-rouge">7daysAgo ~ today</code> 総閲覧数 <code class="language-plaintext highlighter-rouge">screenPageViews</code></p>
  </li>
  <li>
    <p>アクティブユーザー数 <code class="language-plaintext highlighter-rouge">active7DayUsers</code></p>
  </li>
  <li>
    <p>新規ユーザー数 <code class="language-plaintext highlighter-rouge">newUsers</code></p>
  </li>
  <li>
    <p>Top 10 閲覧ページ <code class="language-plaintext highlighter-rouge">screenPageViews</code> / <code class="language-plaintext highlighter-rouge">pageTitle</code></p>
  </li>
  <li>
    <p>新規ユーザーの最初の参照元メディア <code class="language-plaintext highlighter-rouge">newUsers</code> / <code class="language-plaintext highlighter-rouge">firstUserSourceMedium</code></p>
  </li>
</ul>

<blockquote>
  <p><em>実際にはご自身のニーズに合わせて <a href="https://ga-dev-tools.google/ga4/query-explorer/" target="_blank">GA Dev Tools</a> をご利用ください。</em></p>
</blockquote>

<h3 id="step-1-ga4-query-explorer-公式ツール-を使ってデータレポートのクエリパラメータを生成する">Step 1. <a href="https://ga-dev-tools.google/ga4/query-explorer/" target="_blank">GA4 Query Explorer 公式ツール</a> を使ってデータレポートのクエリパラメータを生成する</h3>

<p>まず、<a href="https://ga-dev-tools.google/ga4/query-explorer/" target="_blank">GA4 Query Explorer</a> 公式ツールを使って、必要なクエリデータレポートのパラメータを生成します：</p>

<p><img src="/assets/1e85b8df2348/1*4b1S9nYSmO7OmGgDPllxeQ.webp" alt="" loading="lazy" decoding="async" width="1144" height="1291" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTQ0IiBoZWlnaHQ9IjEyOTEiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/1e85b8df2348/1*4b1S9nYSmO7OmGgDPllxeQ.png" /></p>

<ol>
  <li>
    <p>Select Property: あなたの <code class="language-plaintext highlighter-rouge">property 番号</code> をメモしてください<br />
<strong>property 番号は後で Google Apps Script を作成する際に使用します。</strong></p>
  </li>
  <li>
    <p>start date, end date: レポートの開始日と終了日の範囲。<code class="language-plaintext highlighter-rouge">YYYY-MM-DD</code> または <code class="language-plaintext highlighter-rouge">yesterday</code>、<code class="language-plaintext highlighter-rouge">today</code>、<code class="language-plaintext highlighter-rouge">NdaysAgo</code> のマジック変数が使えます。</p>
  </li>
  <li>
    <p>metrics: 取得したい指標を選択してください</p>
  </li>
  <li>
    <p>dimensions: 取得したいディメンションを選択してください</p>
  </li>
  <li>
    <p>metric aggregations: データの集計方法</p>
  </li>
</ol>

<p>こちらは私のケースを例にします：</p>

<ol>
  <li>
    <p>プロパティ番号: <code class="language-plaintext highlighter-rouge">318495208</code></p>
  </li>
  <li>
    <p>start_date: <code class="language-plaintext highlighter-rouge">7daysAgo</code></p>
  </li>
  <li>
    <p>end_date: <code class="language-plaintext highlighter-rouge">yesterday</code><br />
GAのデータレポートは遅延があるため、前日から7日間のデータを取得するのが最も正確です。</p>
  </li>
  <li>
    <p>metric aggregations: <code class="language-plaintext highlighter-rouge">total</code></p>
  </li>
</ol>

<p><strong>その他の filter や limit は必要に応じて設定可能です：</strong></p>

<p><img src="/assets/1e85b8df2348/1*g2psNn3gMZWs4OFRx7phWQ.webp" alt="" loading="lazy" decoding="async" width="832" height="694" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzIiIGhlaWdodD0iNjk0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/1e85b8df2348/1*g2psNn3gMZWs4OFRx7phWQ.png" /></p>

<p>filter は使わないので空欄にします；limit は 10 と入力します。トップ10だけ知りたいからです。</p>

<h4 id="make-requestをクリックして対応するデータレポートのクエリパラメータと結果を生成"><strong>「MAKE REQUEST」をクリックして対応するデータレポートのクエリパラメータと結果を生成：</strong></h4>

<p><img src="/assets/1e85b8df2348/1*Rj1kMTyZiEYGvAztEEngIQ.webp" alt="" loading="lazy" decoding="async" width="808" height="693" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MDgiIGhlaWdodD0iNjkzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/1e85b8df2348/1*Rj1kMTyZiEYGvAztEEngIQ.png" /></p>

<h4 id="以下のリクエストパラメータをメモしてください後で-google-apps-script-の作成に使用します"><strong>以下のリクエストパラメータをメモしてください。後で Google Apps Script の作成に使用します：</strong></h4>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"dimensions"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"pageTitle"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"metrics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"screenPageViews"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"dateRanges"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"startDate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"7daysAgo"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"endDate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yesterday"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"limit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"10"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"metricAggregations"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"TOTAL"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h4 id="結果"><strong>結果：</strong></h4>

<p><img src="/assets/1e85b8df2348/1*ivAXeRTVB8Y7zbP-Gq2I2A.webp" alt="" loading="lazy" decoding="async" width="801" height="903" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MDEiIGhlaWdodD0iOTAzIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/1e85b8df2348/1*ivAXeRTVB8Y7zbP-Gq2I2A.png" /></p>

<p><img src="/assets/1e85b8df2348/1*FFThyuptIYrGsfddHcjupQ.webp" alt="" loading="lazy" decoding="async" width="1179" height="2556" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTc5IiBoZWlnaHQ9IjI1NTYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/1e85b8df2348/1*FFThyuptIYrGsfddHcjupQ.jpeg" /></p>

<ul>
  <li>GA上のデータとの比較は正確で一致しています ✅✅✅</li>
</ul>

<h3 id="step-2-google-apps-script-を作成しgoogle-analytics-data-api-でデータを取得する">Step 2. Google Apps Script を作成し、Google Analytics Data API でデータを取得する</h3>

<ul>
  <li>
    <p><a href="https://script.google.com/home" target="_blank">https://script.google.com/home</a> にアクセスしてください</p>
  </li>
  <li>
    <p>新しいプロジェクトを作成し、プロジェクト名を設定する</p>
  </li>
  <li>
    <p>「サービス」-&gt;「+」をクリックしてサービスを追加する</p>
  </li>
  <li>
    <p>「Google Analytics Data API」を選択する</p>
  </li>
  <li>
    <p>「追加」をクリックしてください</p>
  </li>
</ul>

<p><img src="/assets/1e85b8df2348/1*gcMDDQTXd-Gos5AdGUXIOw.webp" alt="" loading="lazy" decoding="async" width="1200" height="963" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk2MyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/1e85b8df2348/1*gcMDDQTXd-Gos5AdGUXIOw.png" /></p>

<p><strong>Google Analytics Data API クエリコードの貼り付けと組み合わせ：</strong></p>

<p>前のステップで生成したレポートクエリのデータパラメータ：</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"dimensions"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"pageTitle"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"metrics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"screenPageViews"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"dateRanges"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"startDate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"7daysAgo"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"endDate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yesterday"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"limit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"10"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"metricAggregations"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"TOTAL"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><strong>プログラムに変換：</strong></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">execute</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">Logger</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nf">fetchScreenPageViews</span><span class="p">(</span><span class="dl">"</span><span class="s2">318495208</span><span class="dl">"</span><span class="p">)));</span>
<span class="p">}</span>

<span class="c1">// 独立した関数に分割し、将来の再利用を容易に...</span>
<span class="c1">// デフォルトは startDate=7daysAgo、endDate=yesterday</span>
<span class="c1">// 他の使い方例：</span>
<span class="c1">// 例 fetchScreenPageViews("1111", "3daysAgo", "yesterday")</span>
<span class="c1">// 例 fetchScreenPageViews("2222", "yesterday", "today")</span>
<span class="kd">function</span> <span class="nf">fetchScreenPageViews</span><span class="p">(</span><span class="nx">propertyId</span><span class="p">,</span> <span class="nx">startDate</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">7daysAgo</span><span class="dl">"</span><span class="p">,</span> <span class="nx">endDate</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">yesterday</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">screenPageViewsMetric</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newMetric</span><span class="p">();</span>
  <span class="nx">screenPageViewsMetric</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">screenPageViews</span><span class="dl">"</span><span class="p">;</span>

  <span class="kd">const</span> <span class="nx">dateRange</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newDateRange</span><span class="p">();</span>
  <span class="nx">dateRange</span><span class="p">.</span><span class="nx">startDate</span> <span class="o">=</span> <span class="nx">startDate</span><span class="p">;</span>
  <span class="nx">dateRange</span><span class="p">.</span><span class="nx">endDate</span> <span class="o">=</span> <span class="nx">endDate</span><span class="p">;</span>

  <span class="kd">const</span> <span class="nx">pageTitleDimension</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newDimension</span><span class="p">();</span>
  <span class="nx">pageTitleDimension</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">pageTitle</span><span class="dl">"</span><span class="p">;</span>

  <span class="kd">const</span> <span class="nx">request</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newRunReportRequest</span><span class="p">();</span>
  <span class="nx">request</span><span class="p">.</span><span class="nx">dimensions</span> <span class="o">=</span> <span class="p">[</span><span class="nx">pageTitleDimension</span><span class="p">];</span>
  <span class="nx">request</span><span class="p">.</span><span class="nx">metrics</span> <span class="o">=</span> <span class="p">[</span><span class="nx">screenPageViewsMetric</span><span class="p">];</span>
  <span class="nx">request</span><span class="p">.</span><span class="nx">dateRanges</span> <span class="o">=</span> <span class="nx">dateRange</span><span class="p">;</span>

  <span class="nx">request</span><span class="p">.</span><span class="nx">limit</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
  <span class="nx">request</span><span class="p">.</span><span class="nx">metricAggregations</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">TOTAL</span><span class="dl">"</span><span class="p">;</span>

  <span class="k">return</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nx">Properties</span><span class="p">.</span><span class="nf">runReport</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="dl">"</span><span class="s2">properties/</span><span class="dl">"</span> <span class="o">+</span> <span class="nx">propertyId</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>コード解析：</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// metric 指標、複数の場合はそれぞれ宣言してください...</span>
<span class="kd">const</span> <span class="nx">screenPageViewsMetric</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newMetric</span><span class="p">();</span>
<span class="nx">screenPageViewsMetric</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">screenPageViews</span><span class="dl">"</span><span class="p">;</span>

<span class="c1">// 例として別の指標 active1DayUsers：</span>
<span class="kd">const</span> <span class="nx">active1DayUsersMetric</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newMetric</span><span class="p">();</span>
<span class="nx">active1DayUsersMetric</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">active1DayUsers</span><span class="dl">"</span><span class="p">;</span>

<span class="c1">// 日付範囲の宣言</span>
<span class="kd">const</span> <span class="nx">dateRange</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newDateRange</span><span class="p">();</span>
<span class="nx">dateRange</span><span class="p">.</span><span class="nx">startDate</span> <span class="o">=</span> <span class="nx">startDate</span><span class="p">;</span>
<span class="nx">dateRange</span><span class="p">.</span><span class="nx">endDate</span> <span class="o">=</span> <span class="nx">endDate</span><span class="p">;</span>

<span class="c1">// dimension 次元、複数の場合はそれぞれ宣言してください...</span>
<span class="kd">const</span> <span class="nx">pageTitleDimension</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newDimension</span><span class="p">();</span>
<span class="nx">pageTitleDimension</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">pageTitle</span><span class="dl">"</span><span class="p">;</span>

<span class="c1">// 例として別の dimension：</span>
<span class="kd">const</span> <span class="nx">firstUserSourceMediumDimension</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newDimension</span><span class="p">();</span>
<span class="nx">firstUserSourceMediumDimension</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">firstUserSourceMedium</span><span class="dl">"</span><span class="p">;</span>

<span class="c1">//</span>

<span class="c1">// リクエストオブジェクトの作成</span>
<span class="kd">const</span> <span class="nx">request</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newRunReportRequest</span><span class="p">();</span>
<span class="nx">request</span><span class="p">.</span><span class="nx">metrics</span> <span class="o">=</span> <span class="p">[</span><span class="nx">active1DayUsersMetric</span><span class="p">,</span> <span class="nx">active1DayUsersMetric</span><span class="p">];</span> <span class="c1">// 複数ある場合はすべて指定...</span>
<span class="nx">request</span><span class="p">.</span><span class="nx">dimensions</span> <span class="o">=</span> <span class="p">[</span><span class="nx">pageTitleDimension</span><span class="p">,</span> <span class="nx">firstUserSourceMediumDimension</span><span class="p">];</span> <span class="c1">// 複数ある場合はすべて指定...</span>

<span class="nx">request</span><span class="p">.</span><span class="nx">dateRanges</span> <span class="o">=</span> <span class="nx">dateRange</span><span class="p">;</span>

<span class="c1">// 上位10件のみ取得 (Top 10)</span>
<span class="nx">request</span><span class="p">.</span><span class="nx">limit</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>

<span class="c1">// データ集計ロジックの設定：合計 (SUM)</span>
<span class="nx">request</span><span class="p">.</span><span class="nx">metricAggregations</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">TOTAL</span><span class="dl">"</span><span class="p">;</span>

<span class="c1">// クエリ結果の取得</span>
<span class="k">return</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nx">Properties</span><span class="p">.</span><span class="nf">runReport</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="dl">"</span><span class="s2">properties/</span><span class="dl">"</span> <span class="o">+</span> <span class="nx">propertyId</span><span class="p">).</span><span class="nx">rows</span><span class="p">;</span>
</code></pre></div></div>

<p><strong>初回実行時は認証が必要です（後でコードに新しい権限が追加された場合も再認証が必要になります）：</strong></p>

<blockquote>
  <p><em>実際には、Google Apps Script は今後あなたのアカウント権限でこれらのスクリプトを実行するため、選択したアカウントに対応するGAレポートのアクセス権があることを確認する必要があります。</em></p>
</blockquote>

<p><img src="/assets/1e85b8df2348/1*_z-P8a4PZCozhtgssH82lA.webp" alt="" loading="lazy" decoding="async" width="579" height="477" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NzkiIGhlaWdodD0iNDc3Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/1e85b8df2348/1*_z-P8a4PZCozhtgssH82lA.png" /></p>

<ul>
  <li>コードを書き終えたら、「デバッグ」-&gt;「権限の確認」をクリックしてください。</li>
</ul>

<p><img src="/assets/1e85b8df2348/1*ehox-4AjKv3Ddf1jJ_VmTQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="954" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk1NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/1e85b8df2348/1*ehox-4AjKv3Ddf1jJ_VmTQ.png" /></p>

<ul>
  <li>実行するアカウントを選択します。通常は現在の Google Apps Script アカウントと同じです。</li>
</ul>

<p><img src="/assets/1e85b8df2348/1*onR-n1sI4-G9KhD_fhef3Q.webp" alt="" loading="lazy" decoding="async" width="1265" height="1006" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjY1IiBoZWlnaHQ9IjEwMDYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/1e85b8df2348/1*onR-n1sI4-G9KhD_fhef3Q.png" /></p>

<ul>
  <li>「詳細設定」を展開 -&gt; 「XXX に移動」をクリック<br />
これは自分たち自身が使うためのアプリケーションなので、Google の認証は不要です。</li>
</ul>

<p><img src="/assets/1e85b8df2348/1*73fQnaB__qKhO7NndQ0GyQ.webp" alt="" loading="lazy" decoding="async" width="1200" height="954" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk1NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/1e85b8df2348/1*73fQnaB__qKhO7NndQ0GyQ.png" /></p>

<ul>
  <li>「許可する」をクリックしてください</li>
</ul>

<p><strong>許可後に「デバッグ」や「実行」をクリックするとプログラムを実行できます：</strong></p>

<p><img src="/assets/1e85b8df2348/1*DbcQnfp8xdJCFnrDc778tw.webp" alt="" loading="lazy" decoding="async" width="1265" height="1006" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjY1IiBoZWlnaHQ9IjEwMDYiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/1e85b8df2348/1*DbcQnfp8xdJCFnrDc778tw.png" /></p>

<p>ここではまず <code class="language-plaintext highlighter-rouge">Logger.log(JSON.stringify())</code> を使って出力結果を取得します：</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"kind"</span><span class="p">:</span><span class="w"> </span><span class="s2">"analyticsData#runReport"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"dimensionHeaders"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"pageTitle"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"rowCount"</span><span class="p">:</span><span class="w"> </span><span class="mi">71</span><span class="p">,</span><span class="w">
  </span><span class="nl">"metadata"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"currencyCode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"TWD"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"timeZone"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Asia/Taipei"</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"rows"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ZhgChgLi"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"166"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"109"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Apple Watch 原廠不鏽鋼米蘭錶帶開箱 </span><span class="se">\\</span><span class="s2">| ZhgChgLi"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"iOS ≥ 13.1 使用「捷徑」自動化功能搭配米家智慧家居 </span><span class="se">\\</span><span class="s2">| ZhgChgLi"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"101"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Medium Partner Program 終於對全球(包含台灣)寫作者開放啦！ </span><span class="se">\\</span><span class="s2">| ZhgChgLi"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"85"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"77"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"iOS 捷徑自動化應用場景 — 自動轉發簡訊與自動建立提醒待辦事項 </span><span class="se">\\</span><span class="s2">| ZhgChgLi"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"51"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"遊記 9/11 名古屋一日快閃自由行 </span><span class="se">\\</span><span class="s2">| ZhgChgLi"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"42"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"iOS 隱私與便利的前世今生 </span><span class="se">\\</span><span class="s2">| ZhgChgLi"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"iOS Vision framework x WWDC 24 Discover Swift enhancements in the Vision framework Session </span><span class="se">\\</span><span class="s2">| ZhgChgLi"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"34"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"iOS ≥ 18 NSAttributedString attributes Range 合併的一個行為改變 </span><span class="se">\\</span><span class="s2">| ZhgChgLi"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"30"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"30"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"手工打造 HTML 解析器的那些事 </span><span class="se">\\</span><span class="s2">| ZhgChgLi"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"metricHeaders"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"TYPE_INTEGER"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"screenPageViews"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"totals"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"dimensionValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"RESERVED_TOTAL"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"metricValues"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
          </span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1229"</span><span class="w">
        </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<ul>
  <li><strong>Google Apps Script が GA データの取得に成功しました！🎉🎉🎉</strong></li>
</ul>

<h3 id="step-3-組み合わせるgoogle-apps-script--ga4--telegram-bot">Step 3. 組み合わせる！Google Apps Script + GA4 + Telegram Bot</h3>

<p>上記の記事「 <a href="https://medium.com/zrealm-robotic-process-automation/10-%E5%88%86%E9%90%98%E5%BF%AB%E9%80%9F%E7%A7%BB%E8%BD%89-line-notify-%E5%88%B0-telegram-bot-%E9%80%9A%E7%9F%A5-6922e90ba90c?source=collection_home---6------0-----------------------" target="_blank">10 分鐘快速移轉 Line Notify 到 Telegram Bot 通知</a> 」に従って、Telegram Bot を作成し、<code class="language-plaintext highlighter-rouge">Bot Token</code> と送信したい <code class="language-plaintext highlighter-rouge">Channel Chat ID</code> を取得してください。</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">telegramToken</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">XXXX</span><span class="dl">"</span> <span class="c1">// あなたの Telegram Bot トークンを入力してください</span>
<span class="c1">//</span>

<span class="kd">function</span> <span class="nf">execute</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">screenPageViewsReport</span> <span class="o">=</span> <span class="nf">fetchScreenPageViews</span><span class="p">(</span><span class="dl">"</span><span class="s2">318495208</span><span class="dl">"</span><span class="p">);</span>
  
  <span class="c1">//</span>
  <span class="kd">const</span> <span class="nx">total</span> <span class="o">=</span> <span class="nf">parseInt</span><span class="p">(</span><span class="nx">screenPageViewsReport</span><span class="p">.</span><span class="nx">totals</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">metricValues</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">value</span><span class="p">);</span>
  <span class="kd">var</span> <span class="nx">message</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">総閲覧数：</span><span class="dl">"</span><span class="o">+</span><span class="nx">total</span><span class="p">.</span><span class="nf">toLocaleString</span><span class="p">()</span><span class="o">+</span><span class="dl">"</span><span class="se">\n</span><span class="dl">"</span><span class="p">;</span>

  <span class="nx">screenPageViewsReport</span><span class="p">.</span><span class="nx">rows</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">element</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">pageTitle</span> <span class="o">=</span> <span class="nx">element</span><span class="p">.</span><span class="nx">dimensionValues</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">value</span><span class="p">;</span>
    <span class="kd">const</span> <span class="nx">value</span> <span class="o">=</span> <span class="nf">parseInt</span><span class="p">(</span><span class="nx">element</span><span class="p">.</span><span class="nx">metricValues</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">value</span><span class="p">);</span>

    <span class="nx">message</span> <span class="o">+=</span> <span class="dl">"</span><span class="s2">[Top </span><span class="dl">"</span><span class="o">+</span><span class="p">(</span><span class="nx">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="dl">"</span><span class="s2">] </span><span class="dl">"</span><span class="o">+</span><span class="nx">pageTitle</span><span class="o">+</span><span class="dl">"</span><span class="s2">: </span><span class="dl">"</span><span class="o">+</span><span class="nx">value</span><span class="p">.</span><span class="nf">toLocaleString</span><span class="p">()</span><span class="o">+</span><span class="dl">"</span><span class="se">\n</span><span class="dl">"</span><span class="p">;</span>
  <span class="p">});</span>

  <span class="nf">sendNotifyMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="o">-</span><span class="nx">xxxx</span><span class="p">);</span> <span class="c1">// あなたのチャンネルチャットIDを入力してください</span>
<span class="p">}</span>


<span class="c1">// Telegramの指定チャンネルチャットIDへメッセージを送信</span>
<span class="kd">function</span> <span class="nf">sendNotifyMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">chatId</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://api.telegram.org/bot</span><span class="dl">"</span><span class="o">+</span><span class="nx">telegramToken</span><span class="o">+</span><span class="dl">"</span><span class="s2">/sendMessage</span><span class="dl">"</span><span class="p">;</span>
  
  <span class="kd">const</span> <span class="nx">payload</span> <span class="o">=</span> <span class="p">{</span>
    <span class="dl">"</span><span class="s2">chat_id</span><span class="dl">"</span><span class="p">:</span> <span class="nx">chatId</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="p">:</span> <span class="nx">message</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">disable_web_page_preview</span><span class="dl">"</span><span class="p">:</span> <span class="kc">true</span>
  <span class="p">}</span> 
  <span class="kd">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
    <span class="dl">'</span><span class="s1">method</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">post</span><span class="dl">'</span><span class="p">,</span>
    <span class="dl">'</span><span class="s1">contentType</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">application/json</span><span class="dl">'</span><span class="p">,</span>
    <span class="dl">'</span><span class="s1">muteHttpExceptions</span><span class="dl">'</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="dl">'</span><span class="s1">payload</span><span class="dl">'</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">payload</span><span class="p">)</span>
  <span class="p">};</span>

  <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span>

  <span class="k">if </span><span class="p">(</span><span class="nx">data</span><span class="p">[</span><span class="dl">"</span><span class="s2">ok</span><span class="dl">"</span><span class="p">]</span> <span class="o">==</span> <span class="kc">undefined</span> <span class="err">\\</span><span class="o">|</span><span class="err">\\</span><span class="o">|</span> <span class="nx">data</span><span class="p">[</span><span class="dl">"</span><span class="s2">ok</span><span class="dl">"</span><span class="p">]</span> <span class="o">!=</span> <span class="kc">true</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">data</span><span class="p">[</span><span class="dl">"</span><span class="s2">error_code</span><span class="dl">"</span><span class="p">]</span> <span class="o">!=</span> <span class="kc">undefined</span> <span class="o">&amp;&amp;</span> <span class="nx">data</span><span class="p">[</span><span class="dl">"</span><span class="s2">error_code</span><span class="dl">"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">429</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">Utilities</span><span class="p">.</span><span class="nf">sleep</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
      <span class="nf">sendNotifyMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">chatId</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">fetchScreenPageViews</span><span class="p">(</span><span class="nx">propertyId</span><span class="p">,</span> <span class="nx">startDate</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">7daysAgo</span><span class="dl">"</span><span class="p">,</span> <span class="nx">endDate</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">yesterday</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">screenPageViewsMetric</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newMetric</span><span class="p">();</span>
  <span class="nx">screenPageViewsMetric</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">screenPageViews</span><span class="dl">"</span><span class="p">;</span>

  <span class="kd">const</span> <span class="nx">dateRange</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newDateRange</span><span class="p">();</span>
  <span class="nx">dateRange</span><span class="p">.</span><span class="nx">startDate</span> <span class="o">=</span> <span class="nx">startDate</span><span class="p">;</span>
  <span class="nx">dateRange</span><span class="p">.</span><span class="nx">endDate</span> <span class="o">=</span> <span class="nx">endDate</span><span class="p">;</span>

  <span class="kd">const</span> <span class="nx">pageTitleDimension</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newDimension</span><span class="p">();</span>
  <span class="nx">pageTitleDimension</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">pageTitle</span><span class="dl">"</span><span class="p">;</span>

  <span class="kd">const</span> <span class="nx">request</span> <span class="o">=</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nf">newRunReportRequest</span><span class="p">();</span>
  <span class="nx">request</span><span class="p">.</span><span class="nx">dimensions</span> <span class="o">=</span> <span class="p">[</span><span class="nx">pageTitleDimension</span><span class="p">];</span>
  <span class="nx">request</span><span class="p">.</span><span class="nx">metrics</span> <span class="o">=</span> <span class="p">[</span><span class="nx">screenPageViewsMetric</span><span class="p">];</span>
  <span class="nx">request</span><span class="p">.</span><span class="nx">dateRanges</span> <span class="o">=</span> <span class="nx">dateRange</span><span class="p">;</span>

  <span class="nx">request</span><span class="p">.</span><span class="nx">limit</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
  <span class="nx">request</span><span class="p">.</span><span class="nx">metricAggregations</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">TOTAL</span><span class="dl">"</span><span class="p">;</span>

  <span class="k">return</span> <span class="nx">AnalyticsData</span><span class="p">.</span><span class="nx">Properties</span><span class="p">.</span><span class="nf">runReport</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="dl">"</span><span class="s2">properties/</span><span class="dl">"</span> <span class="o">+</span> <span class="nx">propertyId</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>コード解析：</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">//...</span>
  <span class="c1">// レポートの返却された json から total の位置を見つけ、parseInt で文字列を INT 数値に変換</span>
  <span class="c1">// .toLocaleString() -&gt; 数字のフォーマット、123456 -&gt; 123,456</span>
  <span class="kd">const</span> <span class="nx">total</span> <span class="o">=</span> <span class="nf">parseInt</span><span class="p">(</span><span class="nx">screenPageViewsReport</span><span class="p">.</span><span class="nx">totals</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">metricValues</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">value</span><span class="p">);</span>
  <span class="kd">var</span> <span class="nx">message</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">総閲覧数：</span><span class="dl">"</span><span class="o">+</span><span class="nx">total</span><span class="p">.</span><span class="nf">toLocaleString</span><span class="p">()</span><span class="o">+</span><span class="dl">"</span><span class="se">\n</span><span class="dl">"</span><span class="p">;</span>

  <span class="c1">// レポートの返却された json をループしてデータを組み合わせ、メッセージを作成</span>
  <span class="nx">screenPageViewsReport</span><span class="p">.</span><span class="nx">rows</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">element</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">pageTitle</span> <span class="o">=</span> <span class="nx">element</span><span class="p">.</span><span class="nx">dimensionValues</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">value</span><span class="p">;</span>
    <span class="kd">const</span> <span class="nx">value</span> <span class="o">=</span> <span class="nf">parseInt</span><span class="p">(</span><span class="nx">element</span><span class="p">.</span><span class="nx">metricValues</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">value</span><span class="p">);</span>

    <span class="nx">message</span> <span class="o">+=</span> <span class="dl">"</span><span class="s2">[Top </span><span class="dl">"</span><span class="o">+</span><span class="p">(</span><span class="nx">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="dl">"</span><span class="s2">] </span><span class="dl">"</span><span class="o">+</span><span class="nx">pageTitle</span><span class="o">+</span><span class="dl">"</span><span class="s2">: </span><span class="dl">"</span><span class="o">+</span><span class="nx">value</span><span class="p">.</span><span class="nf">toLocaleString</span><span class="p">()</span><span class="o">+</span><span class="dl">"</span><span class="se">\n</span><span class="dl">"</span><span class="p">;</span>
  <span class="p">});</span>
<span class="c1">//...</span>
</code></pre></div></div>

<h4 id="実行上部の実行またはデバッグをクリックしメソッド名が-execute-になっていることを確認してください"><strong>実行：上部の「実行」または「デバッグ」をクリックし、メソッド名が「 <code class="language-plaintext highlighter-rouge">execute</code> 」になっていることを確認してください：</strong></h4>

<p><img src="/assets/1e85b8df2348/1*R7uVMGODJR2Z_GAYnyMYXA.webp" alt="" loading="lazy" decoding="async" width="512" height="109" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iMTA5Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/1e85b8df2348/1*R7uVMGODJR2Z_GAYnyMYXA.png" /></p>

<p><img src="/assets/1e85b8df2348/1*Pl2v19Ed8COUwCc1deTYFw.webp" alt="" loading="lazy" decoding="async" width="643" height="274" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NDMiIGhlaWdodD0iMjc0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/1e85b8df2348/1*Pl2v19Ed8COUwCc1deTYFw.png" /></p>

<ul>
  <li><strong>成功！🎉🎉🎉</strong></li>
</ul>

<h4 id="スケジュール設定で定期的に自動実行する">スケジュール設定で定期的に自動実行する</h4>

<p>最後のステップは、レポートボットを定期的に自動実行させることです。左側のメニューから「トリガー」へ進みます：</p>

<p><img src="/assets/1e85b8df2348/1*SY1YKLwTvDtP1hQTRqj50w.webp" alt="" loading="lazy" decoding="async" width="866" height="805" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NjYiIGhlaWdodD0iODA1Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/1e85b8df2348/1*SY1YKLwTvDtP1hQTRqj50w.png" /></p>

<ul>
  <li>右下の「トリガーを追加」ボタンを選択してください</li>
</ul>

<p><img src="/assets/1e85b8df2348/1*wYOwwQBTEtns8nN_7bmvNQ.webp" alt="" loading="lazy" decoding="async" width="875" height="874" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzUiIGhlaWdodD0iODc0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/1e85b8df2348/1*wYOwwQBTEtns8nN_7bmvNQ.png" /></p>

<ol>
  <li>
    <p>実行する関数を選択： 「<code class="language-plaintext highlighter-rouge">execute</code>」という関数名を選んでください</p>
  </li>
  <li>
    <p>実行するデプロイを選択： 「<code class="language-plaintext highlighter-rouge">上端</code>」を選択してください</p>
  </li>
  <li>
    <p>トリガーの種類を選択： 「<code class="language-plaintext highlighter-rouge">時間主導</code>」を選択してください</p>
  </li>
  <li>
    <p>時間型トリガーのタイプを選択： 希望するトリガーの頻度を選んでください</p>
  </li>
  <li>
    <p>実行時間の設定： 毎日自動で実行したい時間を選択してください</p>
  </li>
  <li>
    <p>実行失敗時の通知メールの頻度設定</p>
  </li>
  <li>
    <p>保存</p>
  </li>
</ol>

<blockquote>
  <p><strong><em>完了です！これで指定した時間に自動で実行されます。</em></strong> 🎉🎉🎉</p>
</blockquote>

<h3 id="拡張課題">拡張課題</h3>

<p>他のデータ、新規ユーザー数や参照元メディアなども、前述のコードで同様に取得可能です。ここでは繰り返しませんので、皆さんの宿題としてお考えください。</p>

<p><em><a href="https://medium.com/zrealm-robotic-process-automation/%E7%B0%A1%E5%96%AE-3-%E6%AD%A5%E9%A9%9F-%E6%89%93%E9%80%A0%E5%85%8D%E8%B2%BB-ga4-%E8%87%AA%E5%8B%95%E6%95%B8%E6%93%9A%E9%80%9A%E7%9F%A5%E6%A9%9F%E5%99%A8%E4%BA%BA-1e85b8df2348" target="_blank">Post</a> Mediumから変換されたもの <a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>.</em></p>]]></content>
  </entry><entry>
    <title type="html">Line Notify から Telegram Bot への通知移行：10分で完了する無料＆強力な方法｜簡単ステップ解説</title>
    <link href="https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/line-notify-%E3%81%8B%E3%82%89-telegram-bot-%E3%81%B8%E3%81%AE%E9%80%9A%E7%9F%A5%E7%A7%BB%E8%A1%8C-10%E5%88%86%E3%81%A7%E5%AE%8C%E4%BA%86%E3%81%99%E3%82%8B%E7%84%A1%E6%96%99-%E5%BC%B7%E5%8A%9B%E3%81%AA%E6%96%B9%E6%B3%95-%E7%B0%A1%E5%8D%98%E3%82%B9%E3%83%86%E3%83%83%E3%83%97%E8%A7%A3%E8%AA%AC-6922e90ba90c/" rel="alternate" type="text/html" title="Line Notify から Telegram Bot への通知移行：10分で完了する無料＆強力な方法｜簡単ステップ解説" />
    <published>2024-10-12T21:10:46+08:00</published>
    <updated>2024-10-20T16:57:41+08:00</updated>
    <id>https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/6922e90ba90c</id><summary type="html">Line Notify の個人通知を無料でより強力な Telegram Bot に10分で移行する方法を手順通りに解説。通知の安定性と利便性を向上させたい方必見の実践ガイドです。</summary><author>
      <name>ZhgChgLi</name>
    </author><category term="ZRealm ロボティック・プロセス・オートメーション" /><category term="iosアプリ開発" /><category term="line" /><category term="telegram" /><category term="google-apps-script" /><category term="自動化" /><category term="japanese" /><category term="ai-translation" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jp.zhgchg.li/assets/6922e90ba90c/1*r59nJAx__InU09hYMenePg.webp" /><content type="html" xml:base="https://jp.zhgchg.li/posts/zrealm-%E3%83%AD%E3%83%9C%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-%E3%82%AA%E3%83%BC%E3%83%88%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/line-notify-%E3%81%8B%E3%82%89-telegram-bot-%E3%81%B8%E3%81%AE%E9%80%9A%E7%9F%A5%E7%A7%BB%E8%A1%8C-10%E5%88%86%E3%81%A7%E5%AE%8C%E4%BA%86%E3%81%99%E3%82%8B%E7%84%A1%E6%96%99-%E5%BC%B7%E5%8A%9B%E3%81%AA%E6%96%B9%E6%B3%95-%E7%B0%A1%E5%8D%98%E3%82%B9%E3%83%86%E3%83%83%E3%83%97%E8%A7%A3%E8%AA%AC-6922e90ba90c/"><![CDATA[<h3 id="10分でline-notifyからtelegram-bot通知へ素早く移行">10分でLine NotifyからTelegram Bot通知へ素早く移行</h3>

<p>手取り足取りで Line Notify の個人通知サービスを同じく無料でより強力な Telegram Bot に移行する</p>

<p><img src="/assets/6922e90ba90c/1*r59nJAx__InU09hYMenePg.webp" alt="Photo by Lana Codes" loading="lazy" decoding="async" width="1200" height="801" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjgwMSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*r59nJAx__InU09hYMenePg.jpeg" /></p>

<p>Photo by <a href="https://unsplash.com/@lanacodes?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash" target="_blank">Lana Codes</a></p>

<h4 id="line-notifyサービス終了のお知らせ"><a href="https://notify-bot.line.me/closing-announce" target="_blank">LINE Notifyサービス終了のお知らせ</a></h4>

<blockquote>
  <p><em>長い間LINE Notifyをご利用いただき、誠にありがとうございました。</em></p>
</blockquote>

<blockquote>
  <p><em>LINE Notifyは2016年9月のリリース以来、開発者向けのサービスを提供してきました。より良いサービスを提供し、今後の類似商品サービスに経営資源を集中させるため、2025年3月31日をもって本サービスを終了することを決定しました。長年にわたりLINEを通知連携サービスとしてご利用いただいたすべてのユーザーに心より感謝申し上げます。</em></p>
</blockquote>

<blockquote>
  <p><em>もし引き続きLINEでユーザーに通知を送るサービスを利用する場合は、より機能が充実したMessaging APIの利用をおすすめします。</em></p>
</blockquote>

<p><a href="https://notify-bot.line.me/closing-announce" target="_blank">Line Notify公式サイト</a>からの引用で、Lineは2024年10月8日に、Line Notifyが2025年4月1日に完全に終了すると発表しました。引き続きLineで通知を利用する場合は、有料の<a href="https://developers.line.biz/en/services/messaging-api/" target="_blank">Message API</a>のみ利用可能です。</p>

<p>Line Notify の利点は非常に簡単に連携でき、個人通知ロボットとして使うのに非常に便利で使いやすいことです。一部の Line Bot やサードパーティサービスも Line Notify を使って通知を行っています（例：ルイーザ、あなたの注文通知機能など）。しかし、欠点も多く、例えばメッセージ内容が単一であること、グループ分けができないこと（すべて Line Notify Bot に送信される）、メッセージの長さに制限があることなどがあります。</p>

<p>Line Notify の終了が発表されたことで、他の通信・通知サービスへの移行の良い機会となりました：</p>

<ul>
  <li>
    <p>Slack：無料版のメッセージは30日間しか保存されません。私の通知は個人的なものなので、Slackは少しオーバースペックです。（Slackでのメッセージ送信は以前の記事をご参照ください：<a href="/posts/zrealm-ロボティックプロセスオートメーション/slackとchatgpt連携-openai-apiで自作slackアプリをpythonとgoogle-cloud-functionsで実装-bd94cc88f9c9/">Slack &amp; ChatGPT Integration</a>）</p>
  </li>
  <li>
    <p>Discord：私の通知は個人的なもので、少しオーバースペックです。</p>
  </li>
  <li>
    <p><strong>Telegram：無料でほぼ無制限に利用可能。</strong></p>
  </li>
</ul>

<p>私にとって Telegram の通信サービスは、元の Line Notify の使用ニーズにより適しています。通知を受け取るチャンネルが必要で、できれば異なるニーズに応じて複数のチャンネルを持てること、受け入れ可能な内容やフォーマットが豊富であること、そして迅速かつ簡単に連携できることが望ましいです。Telegram はこれらの要件をすべて満たし、さらに Bot との双方向のやり取りも実現できます。</p>

<h4 id="成果">成果</h4>

<p>まず最終的な完成図を掲載します（<a href="/posts/zrealmロボティックプロセスオートメーション/google-apps-script-3ステップで無料構築-github-repo-star通知をline連携で実現-382218e15697/">Github Star 通知、Repo Stats 通知の例</a>）：</p>

<p><img src="/assets/6922e90ba90c/1*1kHJu5yZMUST-wrna6KqkA.gif" alt="" loading="lazy" decoding="async" width="380" height="550" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzODAiIGhlaWdodD0iNTUwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" /></p>

<ul>
  <li>
    <p>✅ 誰かがリポジトリにスターを付けるとWebhookがトリガーされ -&gt; Google Apps Script -&gt; Telegram BotがTelegramのGithub Statsグループに通知を送信します</p>
  </li>
  <li>
    <p>✅ Google Apps Scriptが毎日定時に実行され -&gt; Githubリポジトリのステータスを取得 -&gt; Telegram Botが通知をGithub Statsグループに送信します</p>
  </li>
  <li>
    <p>✅ <code class="language-plaintext highlighter-rouge">/update</code> Telegram Botコマンドを使ってGithubリポジトリのステータスを取得し、Telegram Botが通知をGithub Statsグループに送信します</p>
  </li>
</ul>

<h4 id="元の-line-notify-と比較して">元の Line Notify と比較して</h4>

<p><img src="/assets/6922e90ba90c/1*mTycFPe7rPh1qc0BagUXdw.webp" alt="" loading="lazy" decoding="async" width="960" height="1404" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjAiIGhlaWdodD0iMTQwNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*mTycFPe7rPh1qc0BagUXdw.png" /></p>

<ul>
  <li>
    <p>❌ すべてのメッセージが分類やグループ分けされずに Line Notify に送信される</p>
  </li>
  <li>
    <p>❌ 個別のメッセージに対して特別な設定（通知音、ミュートなど）ができない</p>
  </li>
  <li>
    <p>❌ メッセージのやり取りができない</p>
  </li>
</ul>

<h4 id="目次">目次</h4>

<ul>
  <li>
    <p>Telegram Bot の設定</p>
  </li>
  <li>
    <p>Line Notify のメッセージ送信を Telegram Bot に移行する（Google Apps Script）</p>
  </li>
  <li>
    <p>Telegram Bot との対話（コマンド）× Google Apps Script の活用</p>
  </li>
</ul>

<h3 id="12-telegram-bot-の設定">(1/2) Telegram Bot の設定</h3>

<p>Telegram Bot の申請は非常に簡単で、ウェブページを開く必要もなく、公式の <a href="https://t.me/BotFather" target="_blank">BotFather ロボット</a> とやり取りするだけで済みます。</p>

<h4 id="step-1-telegram-bot-を申請する">Step 1. Telegram Bot を申請する</h4>

<p><a href="https://telegram.org/" target="_blank">Telegramサービスをインストールし登録した後</a>、「<a href="https://t.me/BotFather" target="_blank">BotFather ボット</a>」を友達に追加してください。</p>

<p><img src="/assets/6922e90ba90c/1*-3qluwPXk-HeGRCTOd-EAA.webp" alt="" loading="lazy" decoding="async" width="691" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2OTEiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*-3qluwPXk-HeGRCTOd-EAA.png" /></p>

<p><img src="/assets/6922e90ba90c/1*QfzbJYQ2vVI2CNvvLU7r_w.webp" alt="" loading="lazy" decoding="async" width="595" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1OTUiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*QfzbJYQ2vVI2CNvvLU7r_w.png" /></p>

<ol>
  <li>
    <p>開いて、<a href="https://t.me/BotFather" target="_blank">BotFather ボット</a>に参加します</p>
  </li>
  <li>
    <p>追加後に直接メッセージ「<code class="language-plaintext highlighter-rouge">/newbot</code>」を送信して、あなたのボットを作成します。</p>
  </li>
  <li>
    <p>あなたのボット名を入力してください</p>
  </li>
  <li>
    <p>あなたのボットアカウント名を入力してください（重複不可、必ず <code class="language-plaintext highlighter-rouge">bot</code> で終わる必要があります。例：私のは <code class="language-plaintext highlighter-rouge">zhgchgli_bot</code> です）</p>
  </li>
  <li>
    <p>あなたの Bot のリンク、クリックして使用開始 (例: t.me/harrytest56_bot)</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">あなたの_BOT_API_Token</code> を取得し、<strong>大切に保管してください</strong> ⚠️⚠️⚠️</p>
  </li>
  <li>
    <p>で取得した Bot のリンクをクリックして、Bot の利用を開始します：</p>
  </li>
</ol>

<p><img src="/assets/6922e90ba90c/1*5q5PE3D9nwQPlYoY8SqCHQ.webp" alt="" loading="lazy" decoding="async" width="705" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDUiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*5q5PE3D9nwQPlYoY8SqCHQ.png" /></p>

<p><img src="/assets/6922e90ba90c/1*NKz9GSDlGov9q7xIlHYlCQ.webp" alt="" loading="lazy" decoding="async" width="756" height="1390" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3NTYiIGhlaWdodD0iMTM5MCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*NKz9GSDlGov9q7xIlHYlCQ.png" /></p>

<p><img src="/assets/6922e90ba90c/1*VU7EyeZL2BpVnLRHQBNOPQ.webp" alt="" loading="lazy" decoding="async" width="732" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MzIiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*VU7EyeZL2BpVnLRHQBNOPQ.png" /></p>

<p>現在は機能がありません。右上の「Info」をクリックして、名前の編集やプロフィール画像のアップロードができます。</p>

<h4 id="step-2-telegram通知グループの作成とボットアカウントの参加">Step 2. Telegram通知グループの作成とボットアカウントの参加</h4>

<blockquote>
  <p><em>異なる個人通知タイプを別々のグループに送信したいですが、<strong>デモ用に My Notify Group を1つだけ作成しています</strong>。</em></p>
</blockquote>

<blockquote>
  <p><em>実際のニーズに応じて異なるグループを作成し、手順に従ってボットを追加・設定できます。</em></p>
</blockquote>

<p><img src="/assets/6922e90ba90c/1*geb_lwnJOUXiuLHvguuXjQ.webp" alt="" loading="lazy" decoding="async" width="1040" height="726" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDQwIiBoZWlnaHQ9IjcyNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*geb_lwnJOUXiuLHvguuXjQ.png" /></p>

<p><img src="/assets/6922e90ba90c/1*bfXDTACy4mW3LZlq6ErKzQ.webp" alt="" loading="lazy" decoding="async" width="896" height="1526" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4OTYiIGhlaWdodD0iMTUyNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*bfXDTACy4mW3LZlq6ErKzQ.png" /></p>

<p><img src="/assets/6922e90ba90c/1*ZmsCLqEZbNN3IS2uoZV8cw.webp" alt="" loading="lazy" decoding="async" width="896" height="1526" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4OTYiIGhlaWdodD0iMTUyNiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*ZmsCLqEZbNN3IS2uoZV8cw.png" /></p>

<ol>
  <li>
    <p>新しいグループを作成する</p>
  </li>
  <li>
    <p>あなたのボットアカウントを検索して「参加」をクリックする</p>
  </li>
  <li>
    <p>グループ名とアイコンを設定する</p>
  </li>
</ol>

<h4 id="step-3-グループチャットidを取得する">Step 3. グループチャットIDを取得する</h4>

<p>Telegram Bot API にはグループ一覧やグループチャットIDを直接取得するエンドポイントがありません。<code class="language-plaintext highlighter-rouge">/getUpdates</code> を使ってボットのメッセージリストを取得し、そこからグループチャットIDを見つける必要があります：</p>

<p><strong>リクエスト:</strong></p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">curl</span> <span class="nv">'https</span><span class="p">:</span><span class="c1">//api.telegram.org/bot你的_BOT_API_Token/getUpdates'</span>
</code></pre></div></div>

<ul>
  <li>
    <p>Telegram API の形式は <code class="language-plaintext highlighter-rouge">https://api.telegram.org/bot</code> <strong>あなたの_BOT_API_Token</strong> <code class="language-plaintext highlighter-rouge">/getUpdates</code> で、BOT API Token の前に <code class="language-plaintext highlighter-rouge">bot</code> という文字列を付ける必要があります。</p>
  </li>
  <li>
    <p>例： <code class="language-plaintext highlighter-rouge">curl 'https://api.telegram.org/bot7814194578:AAEWpPJvKn06ID7D9FjV65aDKQLkGkz8cc8/getUpdates'</code></p>
  </li>
</ul>

<p><strong>Response:</strong></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="nl">"ok"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
            </span><span class="nl">"update_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">706454235</span><span class="p">,</span><span class="w">
            </span><span class="nl">"my_chat_member"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                </span><span class="nl">"chat"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">-4532420331</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"My Nofify"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"all_members_are_administrators"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"from"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">986128250</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"is_bot"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"first_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Harry"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"last_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Li"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"zhgchgli"</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"date"</span><span class="p">:</span><span class="w"> </span><span class="mi">1728726861</span><span class="p">,</span><span class="w">
                </span><span class="nl">"old_chat_member"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"user"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                        </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">7814194578</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"is_bot"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"first_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Harry Test"</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"harrytest56_bot"</span><span class="w">
                    </span><span class="p">},</span><span class="w">
                    </span><span class="nl">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"left"</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"new_chat_member"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"user"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                        </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">7814194578</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"is_bot"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"first_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Harry Test"</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"harrytest56_bot"</span><span class="w">
                    </span><span class="p">},</span><span class="w">
                    </span><span class="nl">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"member"</span><span class="w">
                </span><span class="p">}</span><span class="w">
            </span><span class="p">}</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="p">{</span><span class="w">
            </span><span class="nl">"update_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">706454236</span><span class="p">,</span><span class="w">
            </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                </span><span class="nl">"message_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
                </span><span class="nl">"from"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">986128250</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"is_bot"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"first_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Harry"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"last_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Li"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"zhgchgli"</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"chat"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">-4532420331</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"My Nofify"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"all_members_are_administrators"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"date"</span><span class="p">:</span><span class="w"> </span><span class="mi">1728726861</span><span class="p">,</span><span class="w">
                </span><span class="nl">"group_chat_created"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
            </span><span class="p">}</span><span class="w">
        </span><span class="p">},</span><span class="w">
        </span><span class="p">{</span><span class="w">
            </span><span class="nl">"update_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">706454237</span><span class="p">,</span><span class="w">
            </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                </span><span class="nl">"message_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w">
                </span><span class="nl">"from"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">986128250</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"is_bot"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"first_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Harry"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"last_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Li"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"zhgchgli"</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"chat"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
                    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">-4532420331</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"My Nofify"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w">
                    </span><span class="nl">"all_members_are_administrators"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
                </span><span class="p">},</span><span class="w">
                </span><span class="nl">"date"</span><span class="p">:</span><span class="w"> </span><span class="mi">1728726864</span><span class="p">,</span><span class="w">
                </span><span class="nl">"new_chat_photo"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
                    </span><span class="p">{</span><span class="w">
                        </span><span class="nl">"file_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AgACAgUAAxkBAAMCZwpHUEaLZSvFFYu8GiO-8qI_jVYAApfAMRu0B1BUJP-4u2wF6scBAAMCAANhAAM2BA"</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"file_unique_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AQADl8AxG7QHUFQAAQ"</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"file_size"</span><span class="p">:</span><span class="w"> </span><span class="mi">5922</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"width"</span><span class="p">:</span><span class="w"> </span><span class="mi">160</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"height"</span><span class="p">:</span><span class="w"> </span><span class="mi">160</span><span class="w">
                    </span><span class="p">},</span><span class="w">
                    </span><span class="p">{</span><span class="w">
                        </span><span class="nl">"file_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AgACAgUAAxkBAAMCZwpHUEaLZSvFFYu8GiO-8qI_jVYAApfAMRu0B1BUJP-4u2wF6scBAAMCAANiAAM2BA"</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"file_unique_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AQADl8AxG7QHUFRn"</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"file_size"</span><span class="p">:</span><span class="w"> </span><span class="mi">15097</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"width"</span><span class="p">:</span><span class="w"> </span><span class="mi">320</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"height"</span><span class="p">:</span><span class="w"> </span><span class="mi">320</span><span class="w">
                    </span><span class="p">},</span><span class="w">
                    </span><span class="p">{</span><span class="w">
                        </span><span class="nl">"file_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AgACAgUAAxkBAAMCZwpHUEaLZSvFFYu8GiO-8qI_jVYAApfAMRu0B1BUJP-4u2wF6scBAAMCAANjAAM2BA"</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"file_unique_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AQADl8AxG7QHUFQB"</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"file_size"</span><span class="p">:</span><span class="w"> </span><span class="mi">37988</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"width"</span><span class="p">:</span><span class="w"> </span><span class="mi">640</span><span class="p">,</span><span class="w">
                        </span><span class="nl">"height"</span><span class="p">:</span><span class="w"> </span><span class="mi">640</span><span class="w">
                    </span><span class="p">}</span><span class="w">
                </span><span class="p">]</span><span class="w">
            </span><span class="p">}</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>対応する Group Name + type=group のネストされた JSON データをレスポンスから見つけることができ、その中の id が Group Chat ID です:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"chat"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">-4532420331</span><span class="p">,</span><span class="w">
  </span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"My Nofify"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"all_members_are_administrators"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<ul>
  <li><code class="language-plaintext highlighter-rouge">Group Chat Id</code> = <code class="language-plaintext highlighter-rouge">-4532420331</code></li>
</ul>

<blockquote>
  <p><strong><em>⚠️⚠️⚠️️</em></strong> <em>もしレスポンスが空 <code class="language-plaintext highlighter-rouge">{ "ok": true, "result": [] }</code> の場合は、グループ内でメッセージ（例：<code class="language-plaintext highlighter-rouge">Hello</code>）を送ってから再度APIを呼び出してください。</em></p>
</blockquote>

<h4 id="step-4-メッセージを送信する">Step 4. メッセージを送信する</h4>

<p>私たちは <code class="language-plaintext highlighter-rouge">/sendMessage</code> を使ってグループにメッセージを送信できます。</p>

<p><strong>リクエスト:</strong></p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">curl</span> <span class="nv">'https</span><span class="p">:</span><span class="c1">//api.telegram.org/bot你的_BOT_API_Token/sendMessage' \</span>
<span class="o">--</span><span class="n">form</span> <span class="nv">'chat_id</span><span class="o">=</span><span class="s">"グループチャットID"</span><span class="err">'</span> <span class="err">\</span>
<span class="o">--</span><span class="n">form</span> <span class="nv">'text</span><span class="o">=</span><span class="s">"メッセージ内容"</span><span class="err">'</span>
</code></pre></div></div>

<p><strong>例：</strong></p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">curl</span> <span class="nv">'https</span><span class="p">:</span><span class="c1">//api.telegram.org/bot7814194578:AAEWpPJvKn06ID7D9FjV65aDKQLkGkz8cc8/sendMessage' \</span>
<span class="o">--</span><span class="n">form</span> <span class="nv">'chat_id</span><span class="o">=</span><span class="s">"-4532420331"</span><span class="err">'</span> <span class="err">\</span>
<span class="o">--</span><span class="n">form</span> <span class="nv">'text</span><span class="o">=</span><span class="s">"test"</span><span class="err">'</span>
</code></pre></div></div>

<ul>
  <li><a href="https://core.telegram.org/bots/api#sendmessage" target="_blank"><strong>APIパラメータは公式ドキュメントを参照してください</strong></a></li>
</ul>

<p><strong>Response &amp; Result:</strong></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"ok"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
  </span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"message_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="w">
    </span><span class="nl">"from"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">7814194578</span><span class="p">,</span><span class="w">
      </span><span class="nl">"is_bot"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"first_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Harry Test"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"harrytest56_bot"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"chat"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">-4532420331</span><span class="p">,</span><span class="w">
      </span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"My Nofify"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"all_members_are_administrators"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"date"</span><span class="p">:</span><span class="w"> </span><span class="mi">1728727847</span><span class="p">,</span><span class="w">
    </span><span class="nl">"text"</span><span class="p">:</span><span class="w"> </span><span class="s2">"test"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<ul>
  <li>送信に成功し、上記のレスポンスを取得しました</li>
</ul>

<p><img src="/assets/6922e90ba90c/1*WG4ngRKKac1cICU4NvoEJA.webp" alt="" loading="lazy" decoding="async" width="984" height="1614" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5ODQiIGhlaWdodD0iMTYxNCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*WG4ngRKKac1cICU4NvoEJA.png" /></p>

<ul>
  <li>Telegram グループに戻ると、先ほど送信したメッセージ内容が表示されます。</li>
</ul>

<h3 id="22-line-notify-のメッセージ送信を-telegram-bot-に移行するgoogle-apps-script">(2/2) Line Notify のメッセージ送信を Telegram Bot に移行する（Google Apps Script）</h3>

<p>私の個人通知ボットサービスは Google Apps Script を使用しているため、Google Apps Script での変換例（JavaScriptに類似）を示します。</p>

<h4 id="元の-line-notify-送信コード">元の Line Notify 送信コード：</h4>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">lineToken</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">XXXX</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">function</span> <span class="nf">sendLineNotifyMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">https://notify-api.line.me/api/notify</span><span class="dl">'</span><span class="p">;</span>
  
  <span class="kd">var</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">method</span><span class="p">:</span> <span class="dl">'</span><span class="s1">post</span><span class="dl">'</span><span class="p">,</span>
    <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
      <span class="dl">'</span><span class="s1">Authorization</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Bearer </span><span class="dl">'</span><span class="o">+</span><span class="nx">lineToken</span>
    <span class="p">},</span>
    <span class="na">payload</span><span class="p">:</span> <span class="p">{</span>
      <span class="dl">'</span><span class="s1">message</span><span class="dl">'</span><span class="p">:</span> <span class="nx">message</span>  <span class="c1">// 送信するメッセージ</span>
    <span class="p">}</span>
  <span class="p">};</span> 
  <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
  <span class="nx">Logger</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span> <span class="c1">// レスポンスをログに出力</span>
<span class="p">}</span>
</code></pre></div></div>

<p>非常にシンプルで便利に使えることがわかります…</p>

<h4 id="telegram-bot-送信コードへの移行">Telegram Bot 送信コードへの移行：</h4>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">telegramToken</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">あなたの_BOT_API_Token</span><span class="dl">"</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">TelegramChatId</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">GA</span><span class="p">:</span> <span class="o">-</span><span class="mi">123456</span><span class="p">,</span>
  <span class="na">GITHUB</span><span class="p">:</span> <span class="o">-</span><span class="mi">123457</span><span class="p">,</span>
  <span class="na">MEDIUM</span><span class="p">:</span> <span class="o">-</span><span class="mi">123458</span>
<span class="p">};</span>

<span class="kd">function</span> <span class="nf">sendNotifyMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">chatId</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://api.telegram.org/bot</span><span class="dl">"</span><span class="o">+</span><span class="nx">telegramToken</span><span class="o">+</span><span class="dl">"</span><span class="s2">/sendMessage</span><span class="dl">"</span><span class="p">;</span>
  
  <span class="kd">const</span> <span class="nx">payload</span> <span class="o">=</span> <span class="p">{</span>
    <span class="dl">"</span><span class="s2">chat_id</span><span class="dl">"</span><span class="p">:</span> <span class="nx">chatId</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="p">:</span> <span class="nx">message</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">parse_mode</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Markdown</span><span class="dl">"</span>
  <span class="p">}</span> 
  <span class="kd">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
    <span class="dl">'</span><span class="s1">method</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">post</span><span class="dl">'</span><span class="p">,</span>
    <span class="dl">'</span><span class="s1">contentType</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">application/json</span><span class="dl">'</span><span class="p">,</span>
    <span class="dl">'</span><span class="s1">muteHttpExceptions</span><span class="dl">'</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="dl">'</span><span class="s1">payload</span><span class="dl">'</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">payload</span><span class="p">)</span>
  <span class="p">};</span>

  <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
  <span class="nx">Logger</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span>
<span class="p">}</span>
</code></pre></div></div>

<p>前述の Telegram Bot 設定手順で取得した情報。</p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">telegramToken</code> = <code class="language-plaintext highlighter-rouge">あなたの_BOT_API_Token</code></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">TelegramChatId</code> は独自に定義したメソッドです。実際には異なる通知をそれぞれ別のグループに送信したいため、対象グループとその <code class="language-plaintext highlighter-rouge">Group Chat Id</code> を管理する構造体を定義しました。</p>
  </li>
</ul>

<p><code class="language-plaintext highlighter-rouge">/sendMessage</code> <a href="https://core.telegram.org/bots/api#sendmessage" target="_blank"><strong>API パラメータ、その他のパラメータや詳細は公式ドキュメントを参照してください</strong></a> 。以下は私がよく使うパラメータです：</p>

<ul>
  <li>
    <p>text: メッセージ内容（必須）</p>
  </li>
  <li>
    <p>chat_id: 対象のグループチャットID（必須）</p>
  </li>
  <li>
    <p>parse_mode: メッセージ内容の解析方法、ここでは <code class="language-plaintext highlighter-rouge">Markdown</code> を指定しています</p>
  </li>
  <li>
    <p>disable_web_page_preview: メッセージ内のリンクのプレビューを無効にするかどうかです。ここでは <code class="language-plaintext highlighter-rouge">true</code> に設定して無効化し、メッセージをよりシンプルに表示できます。</p>
  </li>
</ul>

<p><strong>使用方法：</strong></p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">sendNotifyMessage</span><span class="o">(</span><span class="s2">"Hello"</span><span class="o">,</span> <span class="nt">TelegramChatId</span><span class="nc">.MEDIUM</span><span class="o">)</span> <span class="o">//</span> <span class="nt">Hello</span> <span class="err">メッセージを</span> <span class="nt">MEDIUM</span> <span class="err">グループチャット</span><span class="nt">ID</span><span class="err">に送信</span>
<span class="nt">sendNotifyMessage</span><span class="o">(</span><span class="s2">"Hello"</span><span class="o">,</span> <span class="nt">-1234</span><span class="o">)</span> <span class="o">//</span> <span class="nt">Hello</span> <span class="err">メッセージを</span> <span class="nt">-1234</span> <span class="err">グループチャット</span><span class="nt">ID</span><span class="err">に送信</span>
</code></pre></div></div>

<h3 id="成果-1">成果</h3>

<p>私の <a href="/posts/zrealmロボティックプロセスオートメーション/google-apps-script-3ステップで無料構築-github-repo-star通知をline連携で実現-382218e15697/">Github Repo Star Notifier ロボット</a> を例に挙げると：</p>

<p><img src="/assets/6922e90ba90c/1*yJDcnb7n1fIJAM-AV1Qk6w.webp" alt="" loading="lazy" decoding="async" width="962" height="1374" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NjIiIGhlaWdodD0iMTM3NCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*yJDcnb7n1fIJAM-AV1Qk6w.png" /></p>

<p><img src="/assets/6922e90ba90c/1*5kBotSkNf9nN8NV-lCwZoQ.webp" alt="" loading="lazy" decoding="async" width="870" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*5kBotSkNf9nN8NV-lCwZoQ.png" /></p>

<ul>
  <li>
    <p>認証成功！誰かが私のリポジトリにスターを付けると、正しくTelegramグループに通知が送信されます！🎉🎉🎉</p>
  </li>
  <li>
    <p>作成方法は、以前の記事「<a href="/posts/zrealmロボティックプロセスオートメーション/google-apps-script-3ステップで無料構築-github-repo-star通知をline連携で実現-382218e15697/">Google Apps Scriptで3ステップ無料でGithub Repo Star Notifierを作る</a>」を参考にしてください。</p>
  </li>
</ul>

<h4 id="特殊な音やサイレントの設定">特殊な音やサイレントの設定</h4>

<p><img src="/assets/6922e90ba90c/1*kQsYkefi0SD7e9t4PerdRA.webp" alt="" loading="lazy" decoding="async" width="1004" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDA0IiBoZWlnaHQ9IjEyMDAiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/6922e90ba90c/1*kQsYkefi0SD7e9t4PerdRA.jpeg" /></p>

<p>Line Notify より優れている点は、異なるグループごとに通知音を設定したり、ミュートにしたりできることです。</p>

<h3 id="telegram-botとの対話コマンド-x-google-apps-scriptの使用">Telegram Botとの対話（コマンド） x Google Apps Scriptの使用</h3>

<p>Notify機能の代替だけでなく、Telegram Botはユーザーとの対話機能—Telegram Bot Command—も簡単に実現できます。</p>

<p>私の使用シナリオに戻ると、私のボットは定期的またはWebhookで通知メッセージを送信します。しかし、時には手動でボットをトリガーして現在の結果をすぐに取得したいこともあります。これまでLine Notifyにはこの機能がなく、Google Apps Scriptの場合は単純にURLを設定して、そのURLを開くとトリガーされるという方法しかなく、とても使いにくかったです。</p>

<p>Telegram Bot Command を使えば、直接コマンドメッセージを入力して、ボットにすぐに実行してほしいことを命令できます。</p>

<blockquote>
  <p><em>本文は <a href="https://script.google.com/home" target="_blank">Goolge Apps Script</a> を例にしています。Google Apps Script の詳細については、以前の記事「<a href="/posts/zrealm-ロボティックプロセスオートメーション/google-apps-scriptで毎日データ報告をrpa自動化-効率化と正確性向上の秘訣-f6713ba3fee3/"><strong>Google サービスの RPA 自動化を Google Apps Script で実現する方法</strong></a>」をご参照ください。</em></p>
</blockquote>

<h4 id="step-1-google-apps-scriptでコマンド処理ロジックを実装する">Step 1. Google Apps Scriptでコマンド処理ロジックを実装する</h4>

<ul>
  <li>
    <p>Google Apps Script ホームページへ移動</p>
  </li>
  <li>
    <p>左上の「新しいプロジェクトを作成」</p>
  </li>
  <li>
    <p>「無題のプロジェクト」をクリックしてプロジェクト名を入力します。例：<code class="language-plaintext highlighter-rouge">Telegram</code></p>
  </li>
  <li>
    <p>貼り付ける基本コード：</p>
  </li>
</ul>

<p><img src="/assets/6922e90ba90c/1*ZeW4O7Mdgcyj0VsSLDpxeA.webp" alt="" loading="lazy" decoding="async" width="1400" height="1288" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjEyODgiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/6922e90ba90c/1*ZeW4O7Mdgcyj0VsSLDpxeA.png" /></p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">telegramToken</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">あなたの_BOT_API_Token</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">function</span> <span class="nf">doPost</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">content</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">postData</span><span class="p">.</span><span class="nx">contents</span><span class="p">);</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">content</span><span class="p">.</span><span class="nx">message</span> <span class="o">&amp;&amp;</span> <span class="nx">content</span><span class="p">.</span><span class="nx">message</span><span class="p">.</span><span class="nx">text</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">command</span> <span class="o">=</span> <span class="nx">content</span><span class="p">.</span><span class="nx">message</span><span class="p">.</span><span class="nx">text</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="dl">'</span><span class="s1"> </span><span class="dl">'</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
    <span class="kd">const</span> <span class="nx">chatId</span> <span class="o">=</span> <span class="nx">content</span><span class="p">.</span><span class="nx">message</span><span class="p">.</span><span class="nx">chat</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>

    <span class="k">if </span><span class="p">(</span><span class="nx">command</span><span class="p">.</span><span class="nf">startsWith</span><span class="p">(</span><span class="dl">"</span><span class="s2">/update</span><span class="dl">"</span><span class="p">))</span> <span class="p">{</span> 
      <span class="c1">// /update コマンドを受信</span>
      <span class="c1">// ここでやりたい処理を行い、応答する...</span>
      <span class="nf">sendNotifyMessage</span><span class="p">(</span><span class="dl">"</span><span class="s2">こんにちは.....</span><span class="se">\n</span><span class="s2">コマンド:</span><span class="dl">"</span><span class="o">+</span><span class="nx">command</span><span class="p">,</span> <span class="nx">chatId</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="nx">HtmlService</span><span class="p">.</span><span class="nf">createHtmlOutput</span><span class="p">(</span><span class="dl">"</span><span class="s2">OK!</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">sendNotifyMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">chatId</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://api.telegram.org/bot</span><span class="dl">"</span><span class="o">+</span><span class="nx">telegramToken</span><span class="o">+</span><span class="dl">"</span><span class="s2">/sendMessage</span><span class="dl">"</span><span class="p">;</span>
  
  <span class="kd">const</span> <span class="nx">payload</span> <span class="o">=</span> <span class="p">{</span>
    <span class="dl">"</span><span class="s2">chat_id</span><span class="dl">"</span><span class="p">:</span> <span class="nx">chatId</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="p">:</span> <span class="nx">message</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">disable_web_page_preview</span><span class="dl">"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="dl">"</span><span class="s2">parse_mode</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Markdown</span><span class="dl">"</span>
  <span class="p">}</span> 
  <span class="kd">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
    <span class="dl">'</span><span class="s1">method</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">post</span><span class="dl">'</span><span class="p">,</span>
    <span class="dl">'</span><span class="s1">contentType</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">application/json</span><span class="dl">'</span><span class="p">,</span>
    <span class="dl">'</span><span class="s1">muteHttpExceptions</span><span class="dl">'</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="dl">'</span><span class="s1">payload</span><span class="dl">'</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">payload</span><span class="p">)</span>
  <span class="p">};</span>

  <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">UrlFetchApp</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
  <span class="nx">Logger</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nf">getContentText</span><span class="p">());</span>
<span class="p">}</span>
</code></pre></div></div>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">telegramToken</code> = <code class="language-plaintext highlighter-rouge">あなたの_BOT_API_Token</code></p>
  </li>
  <li>
    <p>上記のデモプログラムでは、Postリクエストを受け取り、Commandパラメータが<code class="language-plaintext highlighter-rouge">/update</code>の場合に<code class="language-plaintext highlighter-rouge">你好…</code>と応答し、コマンドを受け取って処理した後に応答するシナリオをシミュレートしています。</p>
  </li>
</ul>

<h4 id="step-2-google-apps-script-web-デプロイの完了">Step 2. Google Apps Script Web デプロイの完了</h4>

<p><img src="/assets/6922e90ba90c/1*JfJfs4bYsSfsZYGVkApCSg.webp" alt="" loading="lazy" decoding="async" width="1200" height="705" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjcwNSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*JfJfs4bYsSfsZYGVkApCSg.png" /></p>

<p><img src="/assets/6922e90ba90c/1*TwSm45_Xwv4p7z4o9HJz2w.webp" alt="" loading="lazy" decoding="async" width="1400" height="1109" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjExMDkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/6922e90ba90c/1*TwSm45_Xwv4p7z4o9HJz2w.png" /></p>

<p><img src="/assets/6922e90ba90c/1*7RLJXZ3APnEI4V9bKqp3eg.webp" alt="" loading="lazy" decoding="async" width="1200" height="941" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9Ijk0MSI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*7RLJXZ3APnEI4V9bKqp3eg.png" /></p>

<ul>
  <li>
    <p>右上の「デプロイ」-&gt; 「新しいデプロイを追加」</p>
  </li>
  <li>
    <p>左上の「設定」-&gt;「ウェブアプリケーション」</p>
  </li>
  <li>
    <p>誰でもアクセス可能「全員」</p>
  </li>
</ul>

<p><img src="/assets/6922e90ba90c/1*aRBaOOnhwBeK05l9e3Yv8g.webp" alt="" loading="lazy" decoding="async" width="568" height="380" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NjgiIGhlaWdodD0iMzgwIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6922e90ba90c/1*aRBaOOnhwBeK05l9e3Yv8g.png" /></p>

<p><img src="/assets/6922e90ba90c/1*FtY8NL36peDbOB4JWdzhDA.webp" alt="" loading="lazy" decoding="async" width="1296" height="932" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjk2IiBoZWlnaHQ9IjkzMiI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*FtY8NL36peDbOB4JWdzhDA.png" /></p>

<p><img src="/assets/6922e90ba90c/1*e2E41TCEf5O7nSOnVzpgbw.webp" alt="" loading="lazy" decoding="async" width="1400" height="768" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9Ijc2OCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*e2E41TCEf5O7nSOnVzpgbw.png" /></p>

<ul>
  <li>
    <p>デプロイ作業を追加し、「アクセス権を付与」を選択します。</p>
  </li>
  <li>
    <p>アカウントウィンドウが表示されたら、Googleのログインアカウントを選択してください。</p>
  </li>
  <li>
    <p>警告ウィンドウが表示されたら、「詳細設定」-&gt;「<code class="language-plaintext highlighter-rouge">專案名稱</code> に移動（安全ではありません）」を選択してください。</p>
  </li>
  <li>
    <p>「許可」を選択してください。</p>
  </li>
</ul>

<p><img src="/assets/6922e90ba90c/1*n0iO-XSPqifUKUkIgVQUSg.webp" alt="" loading="lazy" decoding="async" width="1400" height="1109" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDAwIiBoZWlnaHQ9IjExMDkiPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNlZGUyY2YiLz48L3N2Zz4=" data-orig="/assets/6922e90ba90c/1*n0iO-XSPqifUKUkIgVQUSg.png" /></p>

<ul>
  <li>ウェブアプリケーションのURL：<code class="language-plaintext highlighter-rouge">あなたのWebhookのURL</code> <strong>。</strong><br />
コピーしてください。<br />
例：<code class="language-plaintext highlighter-rouge">https://script.google.com/macros/s/AKfycbx2oFv-eB4LezdOk3P3aoEZVhx_PI6n_YnTNP7WVVQSaiRU52di5bKNThsvIZxus3Si/exec</code></li>
</ul>

<blockquote>
  <p><em>Google Apps Script のウェブアプリケーションのデプロイ、更新、使用、デバッグについては、以前の記事「<a href="/posts/zrealm-ロボティックプロセスオートメーション/google-apps-scriptで毎日データ報告をrpa自動化-効率化と正確性向上の秘訣-f6713ba3fee3/"><strong>Google Apps Script を使った Google サービスの RPA 自動化</strong></a>」をご参照ください。</em></p>
</blockquote>

<blockquote>
  <p><strong><em>⚠️⚠️⚠️ ご注意ください。Google Apps Script のコードを変更した場合は、デプロイ → デプロイの管理 → 新しいバージョンを作成を選択しないと反映されません。詳細は上記の記事をご参照ください。</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>⚠️⚠️⚠️ご注意ください。Google Apps Script のコードを変更した場合は、デプロイ -&gt; デプロイの管理 -&gt; 新しいバージョンを作成 を選択しないと反映されません。詳細は上記の記事をご参照ください。</em></strong></p>
</blockquote>

<blockquote>
  <p><strong><em>⚠️⚠️⚠️ご注意ください。Google Apps Script のコードを変更した場合は、デプロイ -&gt; デプロイの管理 -&gt; 新しいバージョンを作成 を選択しないと反映されません。詳細は上記の記事をご参照ください。</em></strong></p>
</blockquote>

<h4 id="step-3-webhookの登録">Step 3. Webhookの登録</h4>

<p>Telegram API の <code class="language-plaintext highlighter-rouge">/setWebhook</code> を使って、あなたの Webhook URL を登録します。</p>

<p><strong>リクエスト:</strong></p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">curl</span> <span class="o">--</span><span class="n">location</span> <span class="nv">'https</span><span class="p">:</span><span class="c1">//api.telegram.org/你的_BOT_API_Token/setWebhook' \</span>
<span class="o">--</span><span class="n">form</span> <span class="nv">'url</span><span class="o">=</span><span class="s">"あなたのWebhookのURL"</span><span class="err">'</span>
</code></pre></div></div>

<p><strong>Response:</strong></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="nl">"ok"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Webhookが設定されました"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h4 id="テスト">テスト</h4>

<p><img src="/assets/6922e90ba90c/1*wNhksFLSip5DC0rXqMA_0A.webp" alt="" loading="lazy" decoding="async" width="870" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*wNhksFLSip5DC0rXqMA_0A.png" /></p>

<p><img src="/assets/6922e90ba90c/1*d_B3h3C30vI61p3ALP77yw.webp" alt="" loading="lazy" decoding="async" width="870" height="1200" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NzAiIGhlaWdodD0iMTIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2VkZTJjZiIvPjwvc3ZnPg==" data-orig="/assets/6922e90ba90c/1*d_B3h3C30vI61p3ALP77yw.png" /></p>

<ul>
  <li>
    <p>私たちは異なる Chat Id に基づいて応答するため、1:1 のボットとのやり取りでも、ボットが参加しているグループチャットでも応答できます。</p>
  </li>
  <li>
    <p>成功 🎉🎉🎉</p>
  </li>
</ul>

<h3 id="次回">次回：</h3>

<ul>
  <li><a href="/posts/zrealm-ロボティック-プロセス-オートメーション/ga4自動数値通知ロボット-無料で作る3ステップ-google-apps-scriptとtelegram-bot連携-1e85b8df2348/">簡単3ステップ — 無料でGA4自動データ通知ボットを作成</a></li>
</ul>

<h3 id="その他の-google-apps-script-自動化記事">その他の Google Apps Script 自動化記事</h3>

<ul>
  <li>
    <p><a href="/posts/zrealm-ロボティックプロセスオートメーション/google-apps-scriptで毎日データ報告をrpa自動化-効率化と正確性向上の秘訣-f6713ba3fee3/">Google Apps Script を使って Google サービスの RPA 自動化を実現する</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealm-ロボティックプロセスオートメーション/slackとchatgpt連携-openai-apiで自作slackアプリをpythonとgoogle-cloud-functionsで実装-bd94cc88f9c9/">Slack &amp; ChatGPT Integration</a></p>
  </li>
  <li>
    <p><a href="/posts/zrealmロボティックプロセスオートメーション/google-apps-script-3ステップで無料構築-github-repo-star通知をline連携で実現-382218e15697/">Google Apps Scriptを使って3ステップで無料でGithubリポジトリスター通知を作成する</a></p>
  </li>
</ul>

<h4 id="備考">備考</h4>

<p><img src="/assets/6922e90ba90c/1*zOFjvO5SSwbJgFL8kMff0w.webp" alt="" loading="lazy" decoding="async" width="706" height="284" lqip="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDYiIGhlaWdodD0iMjg0Ij48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZWRlMmNmIi8+PC9zdmc+" data-orig="/assets/6922e90ba90c/1*zOFjvO5SSwbJgFL8kMff0w.png" /></p>

<p>本文は私の Medium での100本目の記事でもあります（2018年10月に<a href="/posts/zrealm-ライフ/adsense最後收益受け取り方法-blog再開のきっかけと手順を解説-b7a3fb3d5531/">最初の記事</a>を公開し、もう6年になります）。これからも粘り強く努力を続け、詳しい感想やデータはフォロワーが1000人（2024年10月現在925人）または総閲覧数が1,000,000回（2024年10月現在984,549回）を超えた時に改めて共有します。</p>

<p>*<a href="https://medium.com/zrealm-robotic-process-automation/10-%E5%88%86%E9%90%98%E5%BF%AB%E9%80%9F%E7%A7%BB%E8%BD%89-line-notify-%E5%88%B0-telegram-bot-%E9%80%9A%E7%9F%A5-6922e90ba90c" target="_blank">Post</a> Mediumから<a href="https://github.com/ZhgChgLi/ZMediumToMarkdown" target="_blank">ZMediumToMarkdown</a>で変換。</p>]]></content>
  </entry>
</feed>
