VietCat commited on
Commit
4e2f406
·
1 Parent(s): 87eddd1

send message through forwarder

Browse files
Files changed (2) hide show
  1. app/config.py +1 -0
  2. app/facebook.py +87 -29
app/config.py CHANGED
@@ -20,6 +20,7 @@ class Settings(BaseSettings):
20
  # Facebook Configuration
21
  facebook_verify_token: str = os.getenv("FACEBOOK_VERIFY_TOKEN") or ""
22
  facebook_app_secret: str = os.getenv("FACEBOOK_APP_SECRET") or ""
 
23
 
24
  # Google Sheets Configuration
25
  google_sheets_credentials_file: str = os.getenv("GOOGLE_SHEETS_CREDENTIALS_FILE") or ""
 
20
  # Facebook Configuration
21
  facebook_verify_token: str = os.getenv("FACEBOOK_VERIFY_TOKEN") or ""
22
  facebook_app_secret: str = os.getenv("FACEBOOK_APP_SECRET") or ""
23
+ facebook_api_base_url: str = os.getenv("FACEBOOK_API_BASE_URL") or ""
24
 
25
  # Google Sheets Configuration
26
  google_sheets_credentials_file: str = os.getenv("GOOGLE_SHEETS_CREDENTIALS_FILE") or ""
app/facebook.py CHANGED
@@ -2,11 +2,14 @@ import hmac
2
  import hashlib
3
  import json
4
  import asyncio
 
5
  from typing import Any, Dict, Optional
6
  import httpx
7
  from fastapi import HTTPException, Request
8
  from loguru import logger
9
  import facebook
 
 
10
 
11
  from .utils import timing_decorator_async, timing_decorator_sync
12
 
@@ -99,43 +102,98 @@ class FacebookClient:
99
  messages.append(current.rstrip())
100
  return messages
101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  def _send_message_sync(self, page_access_token: str, recipient_id: str, message: str) -> dict:
103
  """
104
  Gửi tin nhắn sử dụng facebook-sdk với request method trực tiếp.
105
  """
106
- try:
107
- graph = facebook.GraphAPI(access_token=page_access_token, version="3.1")
108
-
109
- # Sử dụng request method trực tiếp cho Messenger API
110
- result = graph.request(
111
- path="me/messages",
112
- post_args={
113
- "recipient": {"id": recipient_id},
114
- "message": {"text": message}
115
- }
116
- )
117
- return result
118
- except facebook.GraphAPIError as e:
119
- logger.error(f"Facebook GraphAPI Error: {e}")
120
- raise HTTPException(status_code=500, detail=f"Failed to send message to Facebook: {e}")
121
- except Exception as e:
122
- logger.error(f"Unexpected error sending message to Facebook: {e}")
123
- raise HTTPException(status_code=500, detail="Failed to send message to Facebook")
 
 
 
 
 
 
 
 
 
 
 
124
 
125
  def _get_page_info_sync(self, page_access_token: str, page_id: str) -> dict:
126
  """
127
  Lấy thông tin page sử dụng Facebook SDK.
128
  """
129
- try:
130
- graph = facebook.GraphAPI(access_token=page_access_token, version="3.1")
131
- result = graph.get_object(page_id)
132
- return result
133
- except facebook.GraphAPIError as e:
134
- logger.error(f"Facebook GraphAPI Error getting page info: {e}")
135
- raise HTTPException(status_code=500, detail=f"Failed to get page info: {e}")
136
- except Exception as e:
137
- logger.error(f"Unexpected error getting page info: {e}")
138
- raise HTTPException(status_code=500, detail="Failed to get page info")
 
 
 
 
 
 
 
 
 
 
139
 
140
  @timing_decorator_async
141
  async def send_message(self, page_access_token: Optional[str] = None, recipient_id: Optional[str] = None, message: str = "") -> dict:
@@ -159,7 +217,7 @@ class FacebookClient:
159
  loop = asyncio.get_event_loop()
160
  result = await loop.run_in_executor(
161
  None,
162
- self._send_message_sync,
163
  page_access_token,
164
  recipient_id,
165
  msg
 
2
  import hashlib
3
  import json
4
  import asyncio
5
+ import time
6
  from typing import Any, Dict, Optional
7
  import httpx
8
  from fastapi import HTTPException, Request
9
  from loguru import logger
10
  import facebook
11
+ import requests
12
+ from .config import Settings, get_settings
13
 
14
  from .utils import timing_decorator_async, timing_decorator_sync
15
 
 
102
  messages.append(current.rstrip())
103
  return messages
104
 
105
+ def send_message_forwarder(
106
+ self,
107
+ access_token: str,
108
+ recipient_id: str,
109
+ message: str
110
+ ) -> dict:
111
+ """
112
+ Gửi tin nhắn đến Facebook Messenger qua API được triển khai.
113
+
114
+ Parameters:
115
+ api_base_url (str): Base URL của API, ví dụ "https://your-project.vercel.app"
116
+ recipient_id (str): PSID của người nhận
117
+ access_token (str): Facebook Page Access Token
118
+ message (str): Nội dung tin nhắn
119
+
120
+ Returns:
121
+ dict: Kết quả trả về từ API (JSON)
122
+ """
123
+
124
+ api_base_url = get_settings().facebook_api_base_url
125
+ url = f"{api_base_url.rstrip('/')}/api/send-message"
126
+ payload = {
127
+ "recipient_id": recipient_id,
128
+ "access_token": access_token,
129
+ "message": message
130
+ }
131
+
132
+ try:
133
+ response = requests.post(url, json=payload, timeout=10)
134
+ response.raise_for_status()
135
+ return response.json()
136
+ except requests.RequestException as e:
137
+ return {"error": str(e)}
138
+
139
  def _send_message_sync(self, page_access_token: str, recipient_id: str, message: str) -> dict:
140
  """
141
  Gửi tin nhắn sử dụng facebook-sdk với request method trực tiếp.
142
  """
143
+ max_retries = 3
144
+ retry_delay = 1 # giây
145
+
146
+ for attempt in range(max_retries):
147
+ try:
148
+ graph = facebook.GraphAPI(access_token=page_access_token, version="3.1")
149
+
150
+ # Sử dụng request method trực tiếp cho Messenger API với timeout
151
+ result = graph.request(
152
+ path="me/messages",
153
+ post_args={
154
+ "recipient": {"id": recipient_id},
155
+ "message": {"text": message}
156
+ },
157
+ timeout=30 # Thêm timeout 30 giây
158
+ )
159
+ return result
160
+ except facebook.GraphAPIError as e:
161
+ logger.error(f"Facebook GraphAPI Error (attempt {attempt + 1}/{max_retries}): {e}")
162
+ if attempt == max_retries - 1: # Lần cuối
163
+ raise HTTPException(status_code=500, detail=f"Failed to send message to Facebook: {e}")
164
+ time.sleep(retry_delay)
165
+ retry_delay *= 2 # Exponential backoff
166
+ except Exception as e:
167
+ logger.error(f"Unexpected error sending message to Facebook (attempt {attempt + 1}/{max_retries}): {e}")
168
+ if attempt == max_retries - 1: # Lần cuối
169
+ raise HTTPException(status_code=500, detail="Failed to send message to Facebook")
170
+ time.sleep(retry_delay)
171
+ retry_delay *= 2 # Exponential backoff
172
 
173
  def _get_page_info_sync(self, page_access_token: str, page_id: str) -> dict:
174
  """
175
  Lấy thông tin page sử dụng Facebook SDK.
176
  """
177
+ max_retries = 3
178
+ retry_delay = 1 # giây
179
+
180
+ for attempt in range(max_retries):
181
+ try:
182
+ graph = facebook.GraphAPI(access_token=page_access_token, version="3.1")
183
+ result = graph.get_object(page_id)
184
+ return result
185
+ except facebook.GraphAPIError as e:
186
+ logger.error(f"Facebook GraphAPI Error getting page info (attempt {attempt + 1}/{max_retries}): {e}")
187
+ if attempt == max_retries - 1: # Lần cuối
188
+ raise HTTPException(status_code=500, detail=f"Failed to get page info: {e}")
189
+ time.sleep(retry_delay)
190
+ retry_delay *= 2 # Exponential backoff
191
+ except Exception as e:
192
+ logger.error(f"Unexpected error getting page info (attempt {attempt + 1}/{max_retries}): {e}")
193
+ if attempt == max_retries - 1: # Lần cuối
194
+ raise HTTPException(status_code=500, detail="Failed to get page info")
195
+ time.sleep(retry_delay)
196
+ retry_delay *= 2 # Exponential backoff
197
 
198
  @timing_decorator_async
199
  async def send_message(self, page_access_token: Optional[str] = None, recipient_id: Optional[str] = None, message: str = "") -> dict:
 
217
  loop = asyncio.get_event_loop()
218
  result = await loop.run_in_executor(
219
  None,
220
+ self.send_message_forwarder,
221
  page_access_token,
222
  recipient_id,
223
  msg