Metadata-Version: 2.4
Name: nava-link
Version: 1.0.0
Summary: Python-native messaging client with an embedded runtime
Author: nava_link contributors
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# nava-link

مكتبة Python لإنشاء تطبيقات وبوتات واتساب بواجهة بسيطة. تدعم الاتصال بكود الاقتران، استقبال الرسائل، إرسال النصوص والوسائط، إدارة المجموعات، الحساب، الجلسة، المحادثات، جهات الاتصال والأجهزة.

> المكتبة غير رسمية وغير تابعة لشركة WhatsApp أو Meta. استخدمها وفق القوانين وشروط الخدمة، وتجنب الرسائل المزعجة أو الإرسال العشوائي.

## التثبيت

على Termux:

```bash
pkg update -y
pkg install -y python nodejs-lts
pip install nava-link==1.0.0
```

الاستيراد:

```python
from nava_link import MoXstarClient
```

## الاتصال بكود الاقتران

```python
import asyncio
from nava_link import MoXstarClient

PHONE = "971501234567"

async def main():
    client = MoXstarClient(auth_dir="./auth")
    client.on("ready", lambda _: print("تم الاتصال"))
    client.on("error", lambda error: print("خطأ:", error))

    await client.start()
    await asyncio.sleep(5)
    code = await client.request_pairing_code(PHONE)
    print("كود الاقتران:", code)
    print("واتساب > الإعدادات > الأجهزة المرتبطة > ربط جهاز")
    print("ثم اختر الربط باستخدام رقم الهاتف وأدخل الكود.")

    await client.wait_until_ready()
    await client.wait_closed()

asyncio.run(main())
```

استخدم الرقم الدولي بدون `+` أو مسافات. إذا كانت جلسة `auth` محفوظة، شغّل البرنامج وانتظر الاتصال ولا تطلب كودًا جديدًا.

## الرسائل والوسائط

```python
await client.send_text("201099887766", "مرحبًا من nava-link")
await client.send_message("201099887766", {"text": "رسالة مخصصة"})
await client.send_image("201099887766", "/storage/emulated/0/photo.jpg", "صورة")
await client.send_video("201099887766", "/storage/emulated/0/video.mp4", "فيديو")
await client.send_document("201099887766", "/storage/emulated/0/file.pdf", "file.pdf", "application/pdf")
await client.send_audio("201099887766", "/storage/emulated/0/audio.mp3", "audio/mpeg")
await client.send_location("201099887766", 25.2048, 55.2708, "دبي")
```

## استقبال الرسائل

```python
async def on_messages(event):
    for message in event["messages"]:
        print(message.chat_id, message.sender_id, message.text)
        if message.text == "!ping":
            await client.send_text(message.chat_id, "pong")

client.on("messages.upsert", on_messages)
```

الأحداث: `qr`, `ready`, `messages.upsert`, `messages.update`, `groups.update`, `presence.update`, `contacts.upsert`, `contacts.update`, `close`, `error`, `log`.

```python
client.on("ready", handler)
client.off("ready", handler)
```

## الحساب والحالة

```python
await client.send_presence("composing", "201099887766@s.whatsapp.net")
await client.check_number(["201099887766", "971501234567"])
await client.get_status("201099887766@s.whatsapp.net")
await client.get_profile_picture("201099887766@s.whatsapp.net")
await client.get_blocklist()
await client.update_profile_name("اسم تجريبي")
await client.update_profile_status("متاح الآن")
await client.update_profile_picture("201099887766@s.whatsapp.net", "/storage/emulated/0/profile.jpg")
await client.block("201099887766@s.whatsapp.net", "block")
await client.block("201099887766@s.whatsapp.net", "unblock")
```

## الأجهزة والمحادثات وجهات الاتصال

```python
await client.get_devices()
await client.get_chats()
await client.get_contacts()
```

تعيد المحادثات وجهات الاتصال التي رصدتها الجلسة أثناء التشغيل الحالي.

## الوسائط والرسائل

```python
await client.download_media(message.raw, "/storage/emulated/0/downloaded_file")
await client.forward_message("201099887766", message.raw)
await client.edit_message("201099887766", {"remoteJid": "201099887766@s.whatsapp.net", "fromMe": True, "id": "MESSAGE_ID"}, "النص الجديد")
await client.delete_message({"remoteJid": "201099887766@s.whatsapp.net", "fromMe": True, "id": "MESSAGE_ID"})
await client.mark_as_read([{"remoteJid": "201099887766@s.whatsapp.net", "fromMe": False, "id": "MESSAGE_ID"}])
```

## المجموعات

```python
await client.create_group("مجموعة تجريبية", ["201099887766", "971501234567"])
await client.get_group_info("120363000000000000@g.us")
await client.update_group_subject("120363000000000000@g.us", "اسم جديد")
await client.update_group_description("120363000000000000@g.us", "وصف جديد")
await client.update_group_participants("120363000000000000@g.us", ["201099887766"], "add")
await client.get_group_invite_code("120363000000000000@g.us")
await client.revoke_group_invite("120363000000000000@g.us")
await client.update_group_settings("120363000000000000@g.us", "announcement")
await client.accept_group_invite("INVITE_CODE")
```

إجراءات الأعضاء: `add`, `remove`, `promote`, `demote`.

## إدارة الاتصال

```python
await client.start()
await client.wait_until_ready()
await client.wait_closed()
await client.close()
await client.logout()
print(client.connected, client.alive)
```

## الطلبات المتقدمة

```python
await client.raw_request("fetchStatus", "201099887766@s.whatsapp.net")
await client.relay_message("201099887766@s.whatsapp.net", {"conversation": "رسالة"}, {})
```

استخدم البيانات الصحيحة وبأحجام معقولة فقط. لا ترسل بيانات مصطنعة أو ضخمة، ولا تستخدم المكتبة للإزعاج أو الإغراق.

## قائمة الدوال الكاملة

```text
start, wait_until_ready, wait_closed, request_pairing_code
send_message, send_text, send_image, send_video, send_document, send_audio, send_location
raw_request, relay_message, send_presence, read_messages, mark_as_read
check_number, get_status, get_profile_picture, get_blocklist
update_profile_name, update_profile_status, update_profile_picture, block
get_devices, get_chats, get_contacts, download_media
forward_message, delete_message, edit_message
create_group, get_group_info, update_group_subject, update_group_description
update_group_participants, get_group_invite_code, revoke_group_invite
update_group_settings, accept_group_invite, logout, close, on, off
```

## مثال بوت كامل

```python
import asyncio
from nava_link import MoXstarClient

async def main():
    client = MoXstarClient(auth_dir="./auth")

    async def on_message(event):
        for message in event["messages"]:
            if message.text == "!ping":
                await client.send_text(message.chat_id, "pong")

    client.on("messages.upsert", on_message)
    client.on("ready", lambda _: print("تم الاتصال"))
    client.on("error", lambda error: print("خطأ:", error))
    await client.start()
    await client.wait_until_ready()
    print("البوت يعمل الآن")
    try:
        await client.wait_closed()
    finally:
        await client.close()

asyncio.run(main())
```

## ملاحظات أمنية

- لا تشارك مجلد `auth` أو رمز الاقتران أو QR.
- لا تشغّل نسختين باستخدام مجلد الجلسة نفسه.
- لا تحذف `auth` إذا كنت تريد الاحتفاظ بالجلسة.
- استخدم أرقامًا دولية بدون `+` أو مسافات.
- تجنب الرسائل الجماعية أو المتكررة.

PyPI: https://pypi.org/project/nava-link/
