
SDK تطبيق Hinge للمواعدة للغة بايثون للمهندسين البرمجيين الوحيدين والملولين
SDK بايثون غير رسمي لواجهة برمجة تطبيقات Hinge. تفاعل برمجيًا مع Hinge لجلب التوصيات، وإرسال الرسائل، وتنزيل الوسائط، وأتمتة التفاعلات.
لاستخدام هذا SDK، تحتاج إلى بيانات اعتماد مصادقة صالحة. يمكنك تخزينها في ملف .env أو تمريرها مباشرة إلى العميل.
BEARER_TOKEN: رمز مصادقة JWT الخاص بك (مثال: L2euNWN...).SESSION_ID: UUID الجلسة الحالية.USER_ID: معرف المستخدم/اللاعب الفريد الخاص بك.إذا كنت تريد استخدام حساب Hinge الحالي دون المخاطرة بوضع علامات من تسجيلات الدخول من جهاز جديد، يجب عليك استخراج هذه القيم من حركة مرور الشبكة للتطبيق.
ملاحظة: تحتاج إلى القيام بذلك مرة واحدة فقط للحصول على المتغيرات الصحيحة. بعد التقاطها، يمكنك استخدام طريقة تسجيل الدخول عبر SMS للجلسات المستقبلية.
prod-api.hingeaws.net أو نقاط نهاية Hinge المشابهة.authorization (رمز Bearer)x-session-idx-device-idx-install-idUser ID (غالبًا ما يكون في جسم الرد كـ subjectId أو ما شابه)يمكنك إنشاء بيانات اعتماد جديدة عن طريق تسجيل الدخول عبر SMS من خلال SDK. يؤدي ذلك إلى إجراء عملية تسجيل دخول جديدة.
from hingesdk.client import HingeClient
# يجب أن تتطابق هذه المعرفات مع القيم الفعلية المرتبطة بحسابك.
# لا يمكنك استخدام UUIDs عشوائية؛ يجب أن تتماشى مع الجهاز المسجل للحساب.
client = HingeClient.login_with_sms(
phone_number="+15551234567",
device_id="your_device_id_uuid",
install_id="your_install_id_uuid"
)
print(f"BEARER_TOKEN={client.auth_token}")
print(f"SESSION_ID={client.session_id}")
print(f"USER_ID={client.user_id}")
استنسخ المستودع وقم بتثبيت الحزمة:
git clone https://github.com/reedgraff/hingesdk
cd hingesdk
pip install .
فيما يلي مثال بسيط للمصادقة وجلب توصيات المستخدم.
import os
from hingesdk.api import HingeAPIClient
# التهيئة ببيانات الاعتماد
client = HingeAPIClient(
auth_token=os.getenv("BEARER_TOKEN"),
session_id=os.getenv("SESSION_ID"),
user_id=os.getenv("USER_ID")
)
# جلب التوصيات
recs = client.get_recommendations()
print(f"تم جلب طلب التوصيات بنجاح.")
from hingesdk.client import HingeAPIClient
auth_token = 'your_auth_token'
user_id = 'your_user_id'
client = HingeAPIClient(auth_token=auth_token, user_id=user_id)
response = client.send_message(
subject_id='receiver_id',
message='مرحبًا، هذه رسالة اختبار!'
)
print(response)
from hingesdk.api import HingeAPIClient
client = HingeAPIClient(auth_token=auth_token, user_id=user_id)
recommendations = client.get_recommendations()
print(recommendations)
from hingesdk.tools import HingeTools
from hingesdk.api import HingeAPIClient
from hingesdk.media import HingeMediaClient
api_client = HingeAPIClient(auth_token=auth_token, user_id=user_id)
media_client = HingeMediaClient(auth_token=auth_token)
tools = HingeTools(api_client, media_client)
tools.download_recommendation_content(output_path='path_to_save_images')
import os
import json
from hingesdk.tools import HingeTools
from hingesdk.api import HingeAPIClient
from hingesdk.media import HingeMediaClient
auth_token = os.getenv("BEARER_TOKEN")
session_id = os.getenv("SESSION_ID")
user_id = os.getenv("USER_ID")
api_client = HingeAPIClient(
auth_token=auth_token,
session_id=session_id,
user_id=user_id
)
media_client = HingeMediaClient(auth_token=auth_token)
tools = HingeTools(api_client, media_client)
# مثال: الحصول على معلومات المستخدم
tools.create_profile_json(
source=ProfileSource.STANDOUTS,
output_file="standouts.json"
)
# مثال: إعجاب مستخدم
with open("standouts.json", "r") as f:
profiles = json.load(f)
personData = profiles["35582109789..."]
# إعجاب سؤال مستخدم
questionIDToLike = "5c4a346828fd883a24..."
response = api_client.like_profile(
subject_id=personData["interaction_data"]["subject_id"],
rating_token=personData["interaction_data"]["rating_token"],
prompt={
"questionId": questionIDToLike,
"response": "I've been in Miami for a year and still haven't gone (╥﹏╥)"
}
)
print(response)
# إعجاب صورة مستخدم
# photoIDToLike = "2c6411ac-66e4-4194-..."
# response = api_client.like_profile(
# subject_id=personData["interaction_data"]["subject_id"],
# rating_token=personData["interaction_data"]["rating_token"],
# photo={
# "contentId": photoIDToLike,
# "comment": "So how many people have commented saying they've been here before?"
# }
# )
# print(response)
يوضح هذا المثال كيفية كشط التوصيات وتصفية الملفات الشخصية بناءً على معايير محددة (مثل أفضل الجامعات).
def find_top_50_university_students(json_file_path, age_min=18, age_max=24):
# قائمة لتخزين الملفات الشخصية المتطابقة
matching_profiles = []
# قاموس بأنماط أفضل 50 جامعة (غير حساس لحالة الأحرف)
top_50_patterns = {
"Princeton University": [r"princeton", r"\bpu\b", r"princeton\s+university"],
"Massachusetts Institute of Technology": [r"mit", r"massachusetts\s+institute\s+of\s+technology", r"mass\s+tech"],
"Harvard University": [r"harvard", r"\bhu\b", r"harvard\s+university"],
"Stanford University": [r"stanford", r"\bsu\b", r"stanford\s+university"],
"Yale University": [r"yale", r"\byu\b", r"yale\s+university"],
"California Institute of Technology": [r"caltech", r"california\s+institute\s+of\s+technology"],
"Duke University": [r"duke", r"\bdu\b", r"duke\s+university"],
"Johns Hopkins University": [r"johns\s+hopkins", r"\bjhu\b", r"hopkins"],
"Northwestern University": [r"northwestern", r"\bnu\b", r"northwestern\s+university"],
"University of Pennsylvania": [r"upenn", r"penn", r"university\s+of\s+pennsylvania"],
"Cornell University": [r"cornell", r"\bcu\b", r"cornell\s+university"],
"University of Chicago": [r"uchicago", r"university\s+of\s+chicago", r"u\s+chicago"],
"Brown University": [r"brown", r"\bbu\b", r"brown\s+university"],
"Columbia University": [r"columbia", r"\bcu\b", r"columbia\s+university"],
"Dartmouth College": [r"dartmouth", r"\bdc\b", r"dartmouth\s+college"],
"University of California--Los Angeles": [r"ucla", r"university\s+of\s+california\s+los\s+angeles", r"uc\s+la"],
"University of California, Berkeley": [r"uc\s+berkeley", r"berkeley", r"university\s+of\s+california\s+berkeley"],
"Rice University": [r"rice", r"\bru\b", r"rice\s+university"],
"University of Notre Dame": [r"notre\s+dame", r"\bnd\b", r"university\s+of\s+notre\s+dame"],
"Vanderbilt University": [r"vanderbilt", r"\bvu\b", r"vandy"],
"Carnegie Mellon University": [r"carnegie\s+mellon", r"\bcmu\b", r"cmu"],
"University of Michigan--Ann Arbor": [r"umich", r"michigan", r"university\s+of\s+michigan"],
"Washington University in St. Louis": [r"washu", r"washington\s+university", r"wu\s+stl"],
"Emory University": [r"emory", r"\beu\b", r"emory\s+university"],
"Georgetown University": [r"georgetown", r"\bgu\b", r"georgetown\s+university"],
"University of Virginia": [r"uva", r"virginia", r"university\s+of\s+virginia"],
"University of North Carolina--Chapel Hill": [r"unc", r"chapel\s+hill", r"university\s+of\s+north\s+carolina"],
"University of Southern California": [r"usc", r"southern\s+california", r"university\s+of\s+southern\s+california"],
"University of California, San Diego": [r"ucsd", r"uc\s+san\s+diego", r"university\s+of\s+california\s+san\s+diego"],
"New York University": [r"nyu", r"new\s+york\s+university"],
"University of Florida": [r"uf", r"florida", r"university\s+of\s+florida"],
"The University of Texas--Austin": [r"ut\s+austin", r"utexas", r"university\s+of\s+texas"],
"Georgia Institute of Technology": [r"gatech", r"georgia\s+tech", r"georgia\s+institute\s+of\s+technology"],
"University of California, Davis": [r"uc\s+davis", r"ucd", r"university\s+of\s+california\s+davis"],
"University of California--Irvine": [r"uci", r"uc\s+irvine", r"university\s+of\s+california\s+irvine"],
"University of Illinois Urbana-Champaign": [r"uiuc", r"illinois", r"university\s+of\s+illinois"],
"Boston College": [r"bc", r"boston\s+college"],
"Tufts University": [r"tufts", r"\btu\b", r"tufts\s+university"],
"University of California, Santa Barbara": [r"ucsb", r"uc\s+santa\s+barbara", r"university\s+of\s+california\s+santa\s+barbara"],
"University of Wisconsin--Madison": [r"uw\s+madison", r"wisconsin", r"university\s+of\s+wisconsin"],
"Boston University": [r"bu", r"boston\s+university"],
"The Ohio State University": [r"ohio\s+state", r"osu", r"the\s+ohio\s+state\s+university"],
"Rutgers University--New Brunswick": [r"rutgers", r"ru", r"rutgers\s+university"],
"University of Maryland, College Park": [r"umd", r"maryland", r"university\s+of\s+maryland"],
"University of Rochester": [r"rochester", r"\bur\b", r"university\s+of\s+rochester"],
"Lehigh University": [r"lehigh", r"\blu\b", r"lehigh\s+university"],
"Purdue University--Main Campus": [r"purdue", r"\bpu\b", r"purdue\s+university"],
"University of Georgia": [r"uga", r"georgia", r"university\s+of\s+georgia"],
"University of Washington": [r"uw", r"washington", r"university\s+of\s+washington"],
"Wake Forest University": [r"wake\s+forest", r"\bwfu\b", r"wake"],
"Case Western Reserve University": [r"case\s+western", r"\bcwru\b", r"case"],
"Texas A&M University": [r"texas\s+a&m", r"tamu", r"a&m"],
"Virginia Tech": [r"virginia\s+tech", r"vt", r"vtech"],
"Florida State University": [r"fsu", r"florida\s+state", r"florida\s+state\s+university"],
"University of Miami": [r'umiami', r'\bum\b', r'university\s+of\s+miami']
}
try:
# قراءة ملف JSON
with open(json_file_path, 'r') as file:
data = json.load(file)
# التكرار عبر كل ملف شخصي للمستخدم
for user_id, profile in data.items():
profile_info = profile.get('profile_info', {})
# التحقق من نطاق العمر (الافتراضي إلى الحد الأدنى/الأقصى القابل للتكوين)
age = profile_info.get('age', 0)
if not (age_min <= age <= age_max):
continue
# الحصول على قائمة التعليم (الافتراضي إلى قائمة فارغة إذا لم تكن موجودة)
educations = profile_info.get('educations', [])
# التحقق من كل سلسلة تعليمية للإشارات إلى أفضل 50 جامعة
found_match = False
matched_university = None
for edu in educations:
if not isinstance(edu, str):
continue
# تحويل إلى أحرف صغيرة للمطابقة غير حساسة لحالة الأحرف
edu_lower = edu.lower()
# التحقق من أنماط كل جامعة
for university, patterns in top_50_patterns.items():
for pattern in patterns:
if re.search(pattern, edu_lower):
found_match = True
matched_university = university
break
if found_match:
break
if found_match:
break
# إذا وجدنا تطابقًا، أضف الملف الشخصي إلى نتائجنا
if found_match:
# الحصول على قائمة الصور (الافتراضي إلى قائمة فارغة إذا لم تكن موجودة)
images = profile.get('images', [])
image_urls = [img.get('url', '') for img in images if img.get('url')]
matching_profiles.append({
'user_id': user_id,
'age': age,
'firstName': profile_info.get('firstName', ''),
'educations': educations,
'matched_university': matched_university,
'location': profile_info.get('location', {}).get('name', ''),
'image_urls': image_urls
})
return matching_profiles
except FileNotFoundError:
print(f"خطأ: الملف {json_file_path} غير موجود.")
return []
except json.JSONDecodeError:
print(f"خطأ: تنسيق JSON غير صالح في {json_file_path}.")
return []
except Exception as e:
print(f"خطأ غير متوقع: {str(e)}")
return []
def main():
# تهيئة العملاء باستخدام رمز المصادقة الخاص بك
auth_token = os.getenv("BEARER_TOKEN")
session_id = os.getenv("SESSION_ID")
user_id = os.getenv("USER_ID")
api_client = HingeAPIClient(
auth_token=auth_token,
session_id=session_id,
user_id=user_id
)
media_client = HingeMediaClient(auth_token=auth_token)
tools = HingeTools(api_client, media_client)
# مثال: الكشط الجماعي
# tools.scrape_recommendations_multiple(
# iterations=40, # 40 يبدو الحد الأقصى قبل الحاجة إلى تخطي الأشخاص...
# min_sleep = 20,
# max_sleep = 60,
# )
json_file_path = 'all_recommendations.json'
csv_file_path = 'university_matches.csv'
results = find_top_50_university_students(json_file_path)
print(f"تم العثور على {len(results)} ملفًا شخصيًا متطابقًا.")
# تعريف رؤوس CSV مع أعمدة منفصلة لكل صورة
headers = ['timestamp', 'user_id', 'name', 'age', 'location', 'education',
'image1', 'image2', 'image3', 'image4', 'image5', 'image6']
# فتح ملف CSV في وضع الإلحاق
with open(csv_file_path, 'a', newline='', encoding='utf-8') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=headers)
# كتابة الرؤوس إذا كان الملف فارغًا
if csvfile.tell() == 0:
writer.writeheader()
# كتابة كل ملف شخصي كصف
for profile in results:
# إنشاء قاموس للصف
row_data = {
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'user_id': profile['user_id'],
'name': profile['firstName'],
'age': profile['age'],
'location': profile['location'],
'education': ', '.join(profile['educations'])
}
# إضافة روابط الصور إلى أعمدة منفصلة
for i in range(6):
image_key = f'image{i+1}'
if profile['image_urls'] and i < len(profile['image_urls']):
row_data[image_key] = profile['image_urls'][i]
else:
row_data[image_key] = ''
writer.writerow(row_data)
print(f"تم إلحاق النتائج إلى {csv_file_path}")
تم تنظيم SDK إلى وحدات منطقية لفصل الاهتمامات.
hingesdk/
├── __init__.py
├── client.py # Base HingeClient: يعالج طلبات HTTP والرؤوس والمصادقة
├── api.py # HingeAPIClient: طرق API الأساسية (إعجاب، رسالة، جلب التوصيات)
├── media.py # HingeMediaClient: أدوات مساعدة لتنزيل/معالجة الصور
├── tools.py # HingeTools: سير عمل عالي المستوى (الكشط الجماعي، التصدير)
├── models.py # نماذج Pydantic وهياكل البيانات (إن وجدت)
├── exceptions.py # فئات استثناء مخصصة (HingeAPIError, HingeAuthError)
└── assets/ # موارد ثابتة (مثل تعريفات المحفزات)
هذا المشروع مرخص بموجب رخصة MIT.