Zenaight commited on
Commit
6a40ab9
·
verified ·
1 Parent(s): 8660483

Upload 5 files

Browse files
Files changed (5) hide show
  1. .gitattributes +35 -35
  2. Dockerfile +7 -0
  3. README.md +11 -10
  4. main.py +96 -0
  5. requirements.txt +4 -0
.gitattributes CHANGED
@@ -1,35 +1,35 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+ WORKDIR /code
3
+ COPY requirements.txt .
4
+ RUN pip install --no-cache-dir -r requirements.txt
5
+ COPY . .
6
+ EXPOSE 7860
7
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,10 +1,11 @@
1
- ---
2
- title: WhatsappChatBot
3
- emoji: 🏢
4
- colorFrom: red
5
- colorTo: purple
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
+ ---
2
+ title: WhatsappChatBot
3
+ emoji: 🌖
4
+ colorFrom: yellow
5
+ colorTo: red
6
+ sdk: docker
7
+ pinned: false
8
+ short_description: WhatsApp chat bot for Rumas
9
+ ---
10
+
11
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
main.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os, json
2
+ from fastapi import FastAPI, Request, HTTPException, Query
3
+ from fastapi.responses import PlainTextResponse, JSONResponse
4
+ import httpx
5
+ import base64
6
+
7
+ app = FastAPI()
8
+
9
+ VERIFY_TOKEN = os.getenv("VERIFY_TOKEN", "") # set in HF Secrets
10
+ PHONE_NUMBER_ID = os.getenv("PHONE_NUMBER_ID", "")
11
+ WHATSAPP_API_TOKEN = os.getenv("WHATSAPP_API_TOKEN", "")
12
+
13
+ @app.get("/webhook") # verification
14
+ def verify(
15
+ hub_mode: str = Query(None, alias="hub.mode"),
16
+ hub_token: str = Query(None, alias="hub.verify_token"),
17
+ hub_challenge: str = Query(None, alias="hub.challenge")
18
+ ):
19
+ if hub_mode == "subscribe" and hub_token == VERIFY_TOKEN:
20
+ return PlainTextResponse(hub_challenge)
21
+ raise HTTPException(status_code=403, detail="Invalid token")
22
+
23
+ def send_whatsapp_message(wa_id, reply):
24
+ url = f"https://graph.facebook.com/v23.0/{PHONE_NUMBER_ID}/messages"
25
+ headers = {
26
+ "Authorization": f"Bearer {WHATSAPP_API_TOKEN}",
27
+ "Content-Type": "application/json"
28
+ }
29
+ payload = {
30
+ "messaging_product": "whatsapp",
31
+ "to": wa_id,
32
+ "type": "text",
33
+ "text": {"body": reply}
34
+ }
35
+ httpx.post(url, headers=headers, json=payload)
36
+
37
+ @app.post("/webhook") # incoming WhatsApp updates
38
+ async def receive_update(req: Request):
39
+ data = await req.json()
40
+ try:
41
+ change = data["entry"][0]["changes"][0]["value"]
42
+ contacts = change.get("contacts")
43
+ messages = change.get("messages")
44
+ if not contacts or not messages:
45
+ # Missing expected payload—ignore
46
+ print("Ignoring update, no contacts or messages field")
47
+ return JSONResponse({"status": "ignored", "reason": "no contacts/messages"})
48
+
49
+ wa_id = contacts[0]["wa_id"]
50
+ msg = messages[0]
51
+ except (KeyError, IndexError, TypeError) as e:
52
+ print("Malformed webhook payload:", e)
53
+ return JSONResponse({"status": "ignored", "reason": "malformed payload"})
54
+
55
+ # IMAGE: if user sent an image, convert to Base64 preview
56
+ if msg["type"] == "image":
57
+ media_id = msg["image"]["id"]
58
+ # 1) get media URL
59
+ media_resp = httpx.get(
60
+ f"https://graph.facebook.com/v23.0/{media_id}",
61
+ headers={"Authorization": f"Bearer {WHATSAPP_API_TOKEN}"}
62
+ )
63
+ media_resp.raise_for_status()
64
+ media_url = media_resp.json()["url"]
65
+ # 2) download bytes with auth
66
+ media_bytes = httpx.get(
67
+ media_url,
68
+ headers={"Authorization": f"Bearer {WHATSAPP_API_TOKEN}"}
69
+ ).content
70
+ # 3) encode & preview
71
+ preview = base64.b64encode(media_bytes).decode("utf-8")[:10]
72
+ # send back preview
73
+ send_whatsapp_message(wa_id, f"Base64: {preview}")
74
+ return JSONResponse({"status": "image_preview_sent", "preview": preview})
75
+
76
+ # TEXT: simple echo
77
+ if msg["type"] == "text":
78
+ incoming = msg["text"]["body"]
79
+ reply = f"You said: {incoming}"
80
+ send_whatsapp_message(wa_id, reply)
81
+ return JSONResponse({"status": "replied"})
82
+
83
+ # OTHER: ignore
84
+ return JSONResponse({"status": "ignored", "type": msg["type"]})
85
+
86
+ # health-check endpoint for token
87
+ @app.post("/send")
88
+ async def check_token():
89
+ token = os.getenv("WHATSAPP_API_TOKEN", "")
90
+ if token:
91
+ return {"token_loaded": True}
92
+ raise HTTPException(status_code=400, detail="Token not found")
93
+
94
+ @app.get("/ping") # health check
95
+ def ping():
96
+ return {"pong": True}
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ python-dotenv
4
+ httpx