Skip to content

Commit 355c5cf

Browse files
authored
Merge pull request #1882 from oracle-devrel/matsliwins-patch-2
WhatsApp AI Agent
2 parents e64dbb4 + eaf8a10 commit 355c5cf

19 files changed

+549
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# WhatsApp GenAI Agent on OCI
2+
3+
This repo helps you set up a WhatsApp Generative AI Agent on Oracle Cloud Infrastructure (OCI) using WhatsApp Cloud API. For full step by step refer to the pdf instruction.
4+
5+
## Features
6+
- WhatsApp Cloud API integration
7+
- OCI Generative AI Agent for intelligent messaging
8+
- Simple OCI compute setup
9+
10+
## Requirements
11+
- OCI account
12+
- Meta for Developers account
13+
- Python ≥ 3.12
14+
15+
## Quick Setup
16+
1. Create a WhatsApp Business App in [Meta for Developers](https://developers.facebook.com).
17+
2. Configure `.env`:
18+
```env
19+
ACCESS_TOKEN="<token>"
20+
APP_ID="<app id>"
21+
APP_SECRET="<app secret>"
22+
RECIPIENT_WAID="<phone number>"
23+
VERSION="v22.0"
24+
PHONE_NUMBER_ID="<phone number ID>"
25+
VERIFY_TOKEN="<verify token>"
26+
ENDPOINT="<OCI endpoint>"
27+
COMPARTMENT_ID="<OCI compartment ID>"
28+
AGENT_ENDPOINT_OCID="<OCI agent endpoint>"
29+
```
30+
3. Deploy webhook using OCI Starter and OCI Cloud Shell.
31+
4. Run your app:
32+
```bash
33+
pip3 install -r requirements.txt
34+
python3 run.py
35+
```
36+
37+
## Testing
38+
Use Meta’s WhatsApp sandbox for testing, then switch to verified business numbers for production.
39+
40+
## Troubleshooting
41+
- Confirm Python ≥ 3.12
42+
- Check `.env` configurations
43+
44+
Refer to full guide for detailed instructions.
45+
Binary file not shown.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from flask import Flask
2+
from app.config import load_configurations, configure_logging
3+
from .views import webhook_blueprint
4+
5+
6+
def create_app():
7+
app = Flask(__name__)
8+
9+
# Load configurations and logging settings
10+
load_configurations(app)
11+
configure_logging()
12+
13+
# Import and register blueprints, if any
14+
app.register_blueprint(webhook_blueprint)
15+
16+
return app
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import sys
2+
import os
3+
from dotenv import load_dotenv
4+
import logging
5+
6+
def load_configurations(app):
7+
load_dotenv()
8+
9+
app.config["ACCESS_TOKEN"] = os.getenv("ACCESS_TOKEN")
10+
app.config["APP_ID"] = os.getenv("APP_ID")
11+
app.config["APP_SECRET"] = os.getenv("APP_SECRET")
12+
app.config["RECIPIENT_WAID"] = os.getenv("RECIPIENT_WAID")
13+
app.config["VERSION"] = os.getenv("VERSION")
14+
app.config["PHONE_NUMBER_ID"] = os.getenv("PHONE_NUMBER_ID")
15+
app.config["VERIFY_TOKEN"] = os.getenv("VERIFY_TOKEN")
16+
app.config["ENDPOINT"] = os.getenv("ENDPOINT")
17+
app.config["EMBEDDING_MODEL"] = os.getenv("EMBEDDING_MODEL")
18+
app.config["GENERATE_MODEL"] = os.getenv("GENERATE_MODEL")
19+
app.config["COMPARTMENT_ID"] = os.getenv("COMPARTMENT_ID")
20+
21+
def configure_logging():
22+
logging.basicConfig(
23+
level=logging.INFO,
24+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
25+
stream=sys.stdout,
26+
)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from functools import wraps
2+
from flask import current_app, jsonify, request
3+
import logging
4+
import hashlib
5+
import hmac
6+
7+
8+
def validate_signature(payload, signature):
9+
"""
10+
Validate the incoming payload's signature against our expected signature
11+
"""
12+
# Use the App Secret to hash the payload
13+
expected_signature = hmac.new(
14+
bytes(current_app.config["APP_SECRET"], "latin-1"),
15+
msg=payload.encode("utf-8"),
16+
digestmod=hashlib.sha256,
17+
).hexdigest()
18+
19+
# Check if the signature matches
20+
return hmac.compare_digest(expected_signature, signature)
21+
22+
23+
def signature_required(f):
24+
"""
25+
Decorator to ensure that the incoming requests to our webhook are valid and signed with the correct signature.
26+
"""
27+
28+
@wraps(f)
29+
def decorated_function(*args, **kwargs):
30+
signature = request.headers.get("X-Hub-Signature-256", "")[
31+
7:
32+
] # Removing 'sha256='
33+
if not validate_signature(request.data.decode("utf-8"), signature):
34+
logging.info("Signature verification failed!")
35+
return jsonify({"status": "error", "message": "Invalid signature"}), 403
36+
return f(*args, **kwargs)
37+
38+
return decorated_function

ai/gen-ai-agents/WhatsApp AI Agent/code/app/utils/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)