diff --git a/.gitignore b/.gitignore
index 36b13f1..2d01d00 100644
--- a/.gitignore
+++ b/.gitignore
@@ -174,3 +174,5 @@ cython_debug/
# PyPI configuration file
.pypirc
+# custom
+config.py
diff --git a/README.md b/README.md
index 264184e..50cb162 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,30 @@
-# cfedge-check
+# Cloudflare Edge Location Checker
-Cloudflare Edge Location Checker
\ No newline at end of file
+Cloudflareを使用するサイトに接続するとき、エッジロケーションが想定されている場所になるかを確認します
+その確認結果をMisskeyに投稿します
+
+## Usage
+
+- 引数なし: 確認から結果投稿までを行います
+- `--dry-run`: 確認を行い、結果はMisskeyに投稿せず標準出力に表示します
+
+## Installation
+
+1. Pythonのenvを作る
+```
+python3 -m venv env
+```
+
+2. 必須パッケージをインストール
+```
+env/bin/pip install -U -r requirements.txt
+```
+
+3. config.py をサンプルに従い編集
+
+4. 実行
+```
+env/bin/python3 cfedge.py
+```
+
+cronに登録するなどして自動実行できます
\ No newline at end of file
diff --git a/cfedge.py b/cfedge.py
new file mode 100644
index 0000000..fdc9a85
--- /dev/null
+++ b/cfedge.py
@@ -0,0 +1,62 @@
+# SPDX-FileCopyrightText: 2025 CyberRex
+# SPDX-License-Identifier: MIT
+
+import requests
+import os
+import argparse
+
+class CFSite:
+ def __init__(self, url, plan):
+ self.url = url
+ self.plan = plan
+
+parser = argparse.ArgumentParser(description='Check Cloudflare Edge Locations and post to Misskey.')
+parser.add_argument('--dry-run', action='store_true', help='Run without posting to Misskey')
+args = parser.parse_args()
+
+if os.path.exists('config.py'):
+ import config
+else:
+ print("config.py not found")
+ exit(1)
+
+test_sites = [
+ CFSite('misskey.io', 'Enterprise'),
+ CFSite('misskey.systems', 'Pro'),
+ CFSite('ohtrmi.cbrx.io', 'Free'),
+]
+
+result_txt = []
+result_txt.append('Cloudflare Edge Location Check')
+result_txt.append('')
+
+# read from /cdn-cgi/trace
+for site in test_sites:
+ try:
+ response = requests.get(f"https://{site.url}/cdn-cgi/trace", timeout=5)
+ response.raise_for_status()
+ trace_info = response.text
+ colo_line = next((line for line in trace_info.splitlines() if line.startswith('colo=')), None)
+ if colo_line:
+ colo = colo_line.split('=')[1]
+ if colo in config.expected_edge_locations:
+ result_txt.append(f'- {site.url} ({site.plan}) : {colo}✅️')
+ else:
+ result_txt.append(f'- {site.url} ({site.plan}) : {colo}⚠')
+ else:
+ print(f"Could not find 'colo' in the trace info for {site.url}")
+ except requests.RequestException as e:
+ print(f"Error accessing {site.url}: {e}")
+
+txt = '\n'.join(result_txt)
+
+# post to misskey
+payload = {
+ 'text': txt,
+ 'visibility': 'home'
+}
+
+if not args.dry_run:
+ requests.post(f"{config.misskey_url}/api/notes/create", headers={'Authorization': 'Bearer ' + config.misskey_token}, json=payload)
+else:
+ print(txt)
\ No newline at end of file
diff --git a/config.example.py b/config.example.py
new file mode 100644
index 0000000..b3335a4
--- /dev/null
+++ b/config.example.py
@@ -0,0 +1,11 @@
+# URL of Misskey instance
+misskey_url = 'https://your-misskey-instance.com'
+
+# Access token of Misskey
+# API token with notes:write permission is required
+misskey_token = 'your-misskey-token'
+
+# Expected locations
+# Default is 4 locations in Japan
+# For location codes you want to add, see https://www.feitsui.com/en/article/26
+expected_edge_locations = ['NRT', 'KIX', 'FUK', 'OKA']
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..663bd1f
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+requests
\ No newline at end of file