Mr-Help commited on
Commit
b86c8e7
ยท
verified ยท
1 Parent(s): d80b708

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +50 -63
main.py CHANGED
@@ -1,120 +1,107 @@
1
  # main.py
2
  from fastapi import FastAPI, Request, UploadFile
3
- from typing import Any, Dict
4
  from datetime import datetime
5
- import json
 
6
 
7
  app = FastAPI()
8
 
 
 
9
  def print_human_friendly(payload: Dict[str, Any]) -> None:
10
- """
11
- ูŠุทุจุน ุงู„ุฑูŠูƒูˆุณุช ุจุดูƒู„ ู…ู‚ุฑูˆุก ู„ู„ูŠูˆุฒุฑ + ุฅูŠู…ูˆุฌูŠุฒ
12
- """
13
- # ุชุฑุชูŠุจ ุงู„ุนุฑุถ
14
  order = [
15
- ("client", "๐Ÿ‘ค Client"),
16
- ("source", "๐ŸŒ Source"),
17
- ("event_name", "๐ŸŽฏ Event Name"),
18
- ("event_id", "๐Ÿงพ Event ID"),
19
- ("value", "๐Ÿ’ฐ Value"),
20
- ("currency", "๐Ÿ’ฑ Currency"),
21
- ("transaction_id","๐Ÿ’ณ Transaction ID"),
22
- ("content_id", "๐Ÿ†” Content ID"),
23
- ("content_type", "๐Ÿ“ฆ Content Type"),
24
- ("fbp", "๐Ÿ…ต fbp"),
25
- ("fbc", "๐Ÿ…ต fbc"),
26
- ("ttclid", "๐Ÿ•ธ๏ธ ttclid"),
27
- ("ttp", "๐Ÿช ttp"),
28
- ("scid", "๐ŸŸช scid"),
29
- ("x_email", "๐Ÿ“ง x_email (hashed)"),
30
- ("x_phone", "๐Ÿ“ฑ x_phone (hashed)"),
31
- ("x_fn", "๐Ÿง‘ First Name"),
32
- ("x_ln", "๐Ÿง‘ Last Name"),
33
- ("timestamp", "โฑ๏ธ Timestamp"),
34
- ("client_ua", "๐Ÿ–ฅ๏ธ Client UA"),
35
  ]
36
-
37
  print("\n" + "-"*18 + " ๐Ÿ‘€ Human-friendly view " + "-"*18)
38
-
39
- # ุฃุทุจุน ุงู„ุญู‚ูˆู„ ุงู„ุฃุณุงุณูŠุฉ
40
  label_pad = 20
41
  for key, label in order:
42
- if key in payload and payload.get(key) not in (None, ""):
43
- value = payload.get(key)
44
- print(f"{label:<{label_pad}}: {value}")
45
-
46
- # ุฃุทุจุน ุงู„ุนู†ุงุตุฑ (contents) ุจุดูƒู„ ู…ู†ุณู‚
47
- contents = payload.get("contents")
48
  if isinstance(contents, list):
49
  print("\n๐Ÿงบ Contents:")
50
  for idx, item in enumerate(contents, start=1):
51
  if isinstance(item, dict):
52
- cid = item.get("content_id", "-")
53
- name = item.get("content_name", "-")
54
- price = item.get("price", "-")
55
- qty = item.get("quantity", "-")
56
  print(f" #{idx} โ€ข ID: {cid} | Name: {name} | Price: {price} | Qty: {qty}")
57
  else:
58
  print(f" #{idx} โ€ข {item}")
59
  elif contents is not None:
60
- # ููŠ ุญุงู„ุฉ ุฌุงุช ุณุชุฑู†ุฌ JSON ุฃูˆ ููˆุฑู…ุงุช ู…ุฎุชู„ู
61
  print("\n๐Ÿงบ Contents (raw):")
62
  try:
63
- parsed = contents if isinstance(contents, (dict, list)) else json.loads(str(contents))
64
  print(json.dumps(parsed, ensure_ascii=False, indent=2))
65
  except Exception:
66
  print(str(contents))
67
-
68
  print("-"*60 + "\n")
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  @app.post("/echo")
72
  async def echo(request: Request) -> Dict[str, Any]:
73
  body_bytes = await request.body()
74
  now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
75
 
76
- # ู‡ูŠุฏุฑ ูˆุงุถุญ + ุงู„ูˆู‚ุช
77
  print("\n" + "="*30 + f" ๐Ÿ†• NEW REQUEST ({now}) " + "="*30)
78
 
79
- # ุทุจุงุนุฉ ุงู„ุจูˆุฏูŠ ุงู„ุฎุงู… (ุฒูŠ ู…ุง ู‡ูŠ ุนู†ุฏูƒ)
80
- print("\n๐Ÿ“ Request body:")
81
  raw_text = body_bytes.decode("utf-8", errors="ignore")
 
82
  print(raw_text)
83
  print("="*98)
84
 
85
- # ู…ุญุงูˆู„ุฉ ุชููƒูŠูƒ JSON ุฃูˆ ููˆุฑู…
86
  parsed: Any
87
  try:
88
  parsed = await request.json()
89
  except Exception:
90
  try:
91
- form = await request.form()
92
- parsed = {}
93
- for k, v in form.items():
94
- if isinstance(v, UploadFile):
95
- parsed[k] = {"filename": v.filename, "content_type": v.content_type}
96
- else:
97
- parsed[k] = v
98
  except Exception:
99
- # ู…ุญุงูˆู„ุฉ ุฃุฎูŠุฑุฉ: ู„ูˆ body ู†ุต ุจุณ ููŠู‡ JSON
100
- try:
101
- parsed = json.loads(raw_text)
102
- except Exception:
103
- parsed = raw_text
104
 
105
- # โœ… ุงู„ุทุจุงุนุฉ ุงู„ุฅุถุงููŠุฉ โ€œุงู„ูˆุฏูŠุฉ ู„ู„ุนูŠู†โ€ (ู„ุง ุชุณุชุจุฏู„ ุทุจุงุนุฉ ุงู„ู€ JSON)
106
  if isinstance(parsed, dict):
107
  print_human_friendly(parsed)
108
  else:
109
- print("\n(โ„น๏ธ Human-friendly view skipped: payload is not an object)\n")
 
 
 
 
 
 
 
110
 
111
  return {
112
- "received": parsed,
 
 
113
  "info": {
114
  "method": request.method,
115
  "url": str(request.url),
116
  "headers": dict(request.headers),
117
  },
118
  }
119
-
120
- # ุชุดุบูŠู„: uvicorn main:app --reload --host 0.0.0.0 --port 8000
 
1
  # main.py
2
  from fastapi import FastAPI, Request, UploadFile
3
+ from typing import Any, Dict, Tuple
4
  from datetime import datetime
5
+ import json, os, asyncio
6
+ import httpx # pip install httpx
7
 
8
  app = FastAPI()
9
 
10
+ GAS_WEBAPP_URL = os.getenv("GAS_WEBAPP_URL")
11
+
12
  def print_human_friendly(payload: Dict[str, Any]) -> None:
 
 
 
 
13
  order = [
14
+ ("client","๐Ÿ‘ค Client"),("source","๐ŸŒ Source"),("event_name","๐ŸŽฏ Event Name"),
15
+ ("event_id","๐Ÿงพ Event ID"),("value","๐Ÿ’ฐ Value"),("currency","๐Ÿ’ฑ Currency"),
16
+ ("transaction_id","๐Ÿ’ณ Transaction ID"),("content_id","๐Ÿ†” Content ID"),
17
+ ("content_type","๐Ÿ“ฆ Content Type"),("fbp","๐Ÿ…ต fbp"),("fbc","๐Ÿ…ต fbc"),
18
+ ("ttclid","๐Ÿ•ธ๏ธ ttclid"),("ttp","๐Ÿช ttp"),("scid","๐ŸŸช scid"),
19
+ ("x_email","๐Ÿ“ง x_email (hashed)"),("x_phone","๐Ÿ“ฑ x_phone (hashed)"),
20
+ ("x_fn","๐Ÿง‘ First Name"),("x_ln","๐Ÿง‘ Last Name"),
21
+ ("timestamp","โฑ๏ธ Timestamp"),("client_ua","๐Ÿ–ฅ๏ธ Client UA"),
 
 
 
 
 
 
 
 
 
 
 
 
22
  ]
 
23
  print("\n" + "-"*18 + " ๐Ÿ‘€ Human-friendly view " + "-"*18)
 
 
24
  label_pad = 20
25
  for key, label in order:
26
+ if isinstance(payload, dict) and key in payload and payload.get(key) not in (None, ""):
27
+ print(f"{label:<{label_pad}}: {payload.get(key)}")
28
+ contents = payload.get("contents") if isinstance(payload, dict) else None
 
 
 
29
  if isinstance(contents, list):
30
  print("\n๐Ÿงบ Contents:")
31
  for idx, item in enumerate(contents, start=1):
32
  if isinstance(item, dict):
33
+ cid=item.get("content_id","-"); name=item.get("content_name","-")
34
+ price=item.get("price","-"); qty=item.get("quantity","-")
 
 
35
  print(f" #{idx} โ€ข ID: {cid} | Name: {name} | Price: {price} | Qty: {qty}")
36
  else:
37
  print(f" #{idx} โ€ข {item}")
38
  elif contents is not None:
 
39
  print("\n๐Ÿงบ Contents (raw):")
40
  try:
41
+ parsed = contents if isinstance(contents,(dict,list)) else json.loads(str(contents))
42
  print(json.dumps(parsed, ensure_ascii=False, indent=2))
43
  except Exception:
44
  print(str(contents))
 
45
  print("-"*60 + "\n")
46
 
47
+ async def post_to_gas_raw(raw_body: str, content_type: str) -> Tuple[int, str]:
48
+ """ ูŠุฑุณู„ ุงู„ุจูˆุฏูŠ ูƒู…ุง ู‡ูˆ (RAW) ุฅู„ู‰ GAS ุจู†ูุณ ู†ูˆุน ุงู„ู…ุญุชูˆู‰ """
49
+ if not GAS_WEBAPP_URL or GAS_WEBAPP_URL.startswith("YOUR_"):
50
+ return (0, "GAS_WEBAPP_URL is not configured")
51
+ headers = {"Content-Type": content_type or "application/json"}
52
+ timeout = httpx.Timeout(10.0, connect=5.0)
53
+ async with httpx.AsyncClient(timeout=timeout) as client:
54
+ for attempt in range(1, 3):
55
+ try:
56
+ r = await client.post(GAS_WEBAPP_URL, content=raw_body.encode("utf-8"), headers=headers)
57
+ return (r.status_code, r.text[:5000])
58
+ except Exception as e:
59
+ if attempt == 2:
60
+ return (0, f"Error posting to GAS: {e}")
61
+ await asyncio.sleep(0.5)
62
 
63
  @app.post("/echo")
64
  async def echo(request: Request) -> Dict[str, Any]:
65
  body_bytes = await request.body()
66
  now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
67
 
 
68
  print("\n" + "="*30 + f" ๐Ÿ†• NEW REQUEST ({now}) " + "="*30)
69
 
70
+ # ุงุทุจุน ุงู„ุจูˆุฏูŠ ุงู„ุฎุงู… ูƒู…ุง ู‡ูˆ
 
71
  raw_text = body_bytes.decode("utf-8", errors="ignore")
72
+ print("\n๐Ÿ“ Request body:")
73
  print(raw_text)
74
  print("="*98)
75
 
76
+ # ุญุงูˆู„ ู†ุทุจุนู‡ ุจุดูƒู„ ูˆุฏู‘ูŠ ูู‚ุท ู„ูˆ JSON object (ู„ู„ุนุฑุถ ูู‚ุทุŒ ุจุฏูˆู† ุชุนุฏูŠู„ ุงู„ุจูŠุงู†ุงุช)
77
  parsed: Any
78
  try:
79
  parsed = await request.json()
80
  except Exception:
81
  try:
82
+ parsed = json.loads(raw_text)
 
 
 
 
 
 
83
  except Exception:
84
+ parsed = None
 
 
 
 
85
 
 
86
  if isinstance(parsed, dict):
87
  print_human_friendly(parsed)
88
  else:
89
+ print("\n(โ„น๏ธ Human-friendly view skipped: payload is not a JSON object)\n")
90
+
91
+ # ๐Ÿš€ ุงุจุนุช ู„ู„ู€ GAS ูƒู…ุง ู‡ูˆ (RAW) ุจู†ูุณ content-type ุงู„ู„ูŠ ุฌู‡
92
+ ct = request.headers.get("content-type", "application/json")
93
+ gas_status, gas_body = await post_to_gas_raw(raw_text, ct)
94
+ print(f"๐Ÿ“ค GAS post status: {gas_status}")
95
+ if gas_body:
96
+ print(f"๐Ÿ”Ž GAS response: {gas_body[:1000]}")
97
 
98
  return {
99
+ "received": parsed if isinstance(parsed, dict) else raw_text,
100
+ "forwarded_to_gas": True,
101
+ "gas_status": gas_status,
102
  "info": {
103
  "method": request.method,
104
  "url": str(request.url),
105
  "headers": dict(request.headers),
106
  },
107
  }