izuemon commited on
Commit
862f6ba
·
verified ·
1 Parent(s): a195df1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -139
app.py CHANGED
@@ -1,122 +1,19 @@
 
1
  import os
2
- import time
3
- import threading
4
  import requests
5
- from datetime import datetime, timezone
6
- from flask import Flask, request, jsonify, redirect, Response
7
 
8
- # =========================
9
- # Channel.io 監視設定
10
- # =========================
11
- CHANNEL_ID = "200605"
12
- GROUP_ID = "519217"
13
-
14
- CHANNEL_MESSAGE_URL = (
15
- f"https://desk-api.channel.io/desk/channels/{CHANNEL_ID}/groups/{GROUP_ID}/messages"
16
- )
17
-
18
- PARAMS = {
19
- "sortOrder": "desc",
20
- "limit": 36,
21
- "logFolded": "false",
22
- }
23
-
24
- X_ACCOUNT_BOT = os.getenv("channeliotokenbot2")
25
- if not X_ACCOUNT_BOT:
26
- raise RuntimeError("環境変数 channeliotokenbot2 が設定されていません")
27
-
28
- BOT_HEADERS = {
29
- "accept": "application/json",
30
- "accept-language": "ja",
31
- "x-account": X_ACCOUNT_BOT,
32
- }
33
-
34
- # =========================
35
- # Flask 設定
36
- # =========================
37
  app = Flask(__name__)
38
 
39
- # =========================
40
- # 共通関数
41
- # =========================
42
- def parse_updated_at(value):
43
- """updatedAt が int(ms) / ISO8601 の両対応"""
44
- try:
45
- if isinstance(value, (int, float)):
46
- return datetime.fromtimestamp(value / 1000, tz=timezone.utc)
47
- if isinstance(value, str):
48
- return datetime.fromisoformat(value.replace("Z", "+00:00"))
49
- except Exception:
50
- pass
51
- return None
52
-
53
-
54
- # =========================
55
- # Channel.io 監視スレッド
56
- # =========================
57
- def watch_channel_messages():
58
- print("▶ Channel.io message watcher started")
59
-
60
- while True:
61
- try:
62
- res = requests.get(
63
- CHANNEL_MESSAGE_URL,
64
- headers=BOT_HEADERS,
65
- params=PARAMS,
66
- timeout=30,
67
- )
68
- res.raise_for_status()
69
-
70
- data = res.json()
71
- messages = data.get("messages", [])
72
-
73
- latest_msg = None
74
- latest_time = None
75
-
76
- for msg in messages:
77
- plain_text = msg.get("plainText")
78
- updated_at = msg.get("updatedAt")
79
-
80
- if not plain_text or updated_at is None:
81
- continue
82
-
83
- updated_time = parse_updated_at(updated_at)
84
- if updated_time is None:
85
- continue
86
-
87
- if latest_time is None or updated_time > latest_time:
88
- latest_time = updated_time
89
- latest_msg = msg
90
-
91
- if latest_msg:
92
- print(
93
- f"[{latest_time.isoformat()}] {latest_msg['plainText']}"
94
- )
95
- else:
96
- print("条件に合う message が見つかりませんでした")
97
-
98
- except Exception as e:
99
- # スレッドが死なないように必ず catch
100
- print("⚠ watcher error:", e)
101
-
102
- time.sleep(60)
103
-
104
-
105
- # =========================
106
- # Flask ルーティング
107
- # =========================
108
  @app.route("/drive.com/files")
109
- def drive_redirect():
110
  ip = request.remote_addr
111
  print(f"アクセスIP: {ip}")
112
  return redirect("https://drive.google.com/")
113
 
114
-
115
  @app.route("/channel-io-managers")
116
  def get_managers():
117
  limit = request.args.get("limit")
118
  since = request.args.get("since")
119
- channel_id = request.args.get("channelid", CHANNEL_ID)
120
 
121
  params = {}
122
  if limit:
@@ -124,6 +21,7 @@ def get_managers():
124
  if since:
125
  params["since"] = since
126
 
 
127
  url = f"https://desk-api.channel.io/desk/channels/{channel_id}/managers"
128
 
129
  headers = {
@@ -132,57 +30,57 @@ def get_managers():
132
  }
133
 
134
  res = requests.get(url, headers=headers, params=params)
 
135
  if res.status_code != 200:
136
  return jsonify({"error": res.text}), res.status_code
137
 
138
  return jsonify(res.json().get("managers", []))
139
 
140
-
141
- @app.route("/cors-proxy", methods=["GET", "POST", "PATCH", "OPTIONS"])
142
- def cors_proxy():
143
  url = request.args.get("url")
144
  if not url:
145
  return "url パラメータが必要です", 400
146
 
147
  if not url.startswith(("http://", "https://")):
148
- return "http / https のURLのみ使用できます", 400
149
 
150
- try:
151
- resp = requests.request(
152
- method=request.method,
153
- url=url,
154
- headers={k: v for k, v in request.headers if k.lower() != "host"},
155
- data=request.get_data(),
156
- timeout=60,
157
- )
158
 
159
- response = Response(resp.content, resp.status_code)
 
 
 
160
 
161
- response.headers["Access-Control-Allow-Origin"] = "*"
162
- response.headers["Access-Control-Allow-Headers"] = "*"
163
- response.headers["Access-Control-Allow-Methods"] = "GET, POST, PATCH, OPTIONS"
164
 
165
- if "Content-Type" in resp.headers:
166
- response.headers["Content-Type"] = resp.headers["Content-Type"]
167
 
168
- return response
 
 
 
 
 
 
 
169
 
170
- except Exception as e:
171
- return f"エラー: {str(e)}", 500
 
 
 
 
 
 
 
 
 
 
 
172
 
 
173
 
174
- # =========================
175
- # エントリーポイント
176
- # =========================
177
  if __name__ == "__main__":
178
- # Flask debug の二重起動防止
179
- if os.environ.get("WERKZEUG_RUN_MAIN") == "true" or not app.debug:
180
- watcher = threading.Thread(
181
- target=watch_channel_messages,
182
- daemon=True,
183
- name="ChannelWatcher",
184
- )
185
- watcher.start()
186
-
187
- print("▶ Flask server starting")
188
  app.run(debug=True, host="0.0.0.0", port=7860)
 
1
+ from flask import Flask, request, jsonify, redirect, Response
2
  import os
 
 
3
  import requests
 
 
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  app = Flask(__name__)
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  @app.route("/drive.com/files")
8
+ def index():
9
  ip = request.remote_addr
10
  print(f"アクセスIP: {ip}")
11
  return redirect("https://drive.google.com/")
12
 
 
13
  @app.route("/channel-io-managers")
14
  def get_managers():
15
  limit = request.args.get("limit")
16
  since = request.args.get("since")
 
17
 
18
  params = {}
19
  if limit:
 
21
  if since:
22
  params["since"] = since
23
 
24
+ channel_id = request.args.get("channelid", "200605")
25
  url = f"https://desk-api.channel.io/desk/channels/{channel_id}/managers"
26
 
27
  headers = {
 
30
  }
31
 
32
  res = requests.get(url, headers=headers, params=params)
33
+
34
  if res.status_code != 200:
35
  return jsonify({"error": res.text}), res.status_code
36
 
37
  return jsonify(res.json().get("managers", []))
38
 
39
+ @app.route("/cors-proxy", methods=["GET"])
40
+ def corsproxy():
 
41
  url = request.args.get("url")
42
  if not url:
43
  return "url パラメータが必要です", 400
44
 
45
  if not url.startswith(("http://", "https://")):
46
+ return "http または https のURLのみ使用できます", 400
47
 
48
+ resp = requests.get(url, headers=request.headers, timeout=60)
 
 
 
 
 
 
 
49
 
50
+ response = Response(resp.content, resp.status_code)
51
+ response.headers["Access-Control-Allow-Origin"] = "*"
52
+ response.headers["Access-Control-Allow-Headers"] = "*"
53
+ response.headers["Access-Control-Allow-Methods"] = "GET, POST, PATCH, OPTIONS"
54
 
55
+ if "Content-Type" in resp.headers:
56
+ response.headers["Content-Type"] = resp.headers["Content-Type"]
 
57
 
58
+ return response
 
59
 
60
+ @app.route("/cors-proxy", methods=["POST", "PATCH"])
61
+ def corsproxy_post():
62
+ url = request.args.get("url")
63
+ if not url:
64
+ return "url パラメータが必要です", 400
65
+
66
+ if not url.startswith(("http://", "https://")):
67
+ return "http または https のURLのみ使用できます", 400
68
 
69
+ resp = requests.request(
70
+ method=request.method,
71
+ url=url,
72
+ headers=request.headers,
73
+ data=request.data,
74
+ timeout=60,
75
+ )
76
+
77
+ headers = {
78
+ "Access-Control-Allow-Origin": "*",
79
+ "Access-Control-Allow-Headers": "*",
80
+ "Access-Control-Allow-Methods": "GET, POST, PATCH, OPTIONS",
81
+ }
82
 
83
+ return Response(resp.content, resp.status_code, headers=headers)
84
 
 
 
 
85
  if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
86
  app.run(debug=True, host="0.0.0.0", port=7860)