AI Agents · درس

إنشاء أحداث التقويم والاستعلام عنها

Google Calendar API: عرض الأحداث، وإنشاء الاجتماعات، وضبط التذكيرات

الدرس 3 من 413 خطوة

إنشاء أحداث التقويم والاستعلام عنها درس مجاني في AI Agents على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Agents، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Agents 4 دروس في المجموع.

نظرة عامة على Google Calendar API

تتيح Google Calendar API للوكلاء قراءة أحداث التقويم وإنشاءها وتحديثها وحذفها. وهي تستخدم مصادقة Google OAuth نفسها التي يستخدمها Gmail. المورد الأساسي هو الكائن Event، وتنتمي الأحداث إلى Calendar. ويشير معرّف التقويم 'primary' إلى التقويم الرئيسي للمستخدم الذي تمت مصادقته.

from googleapiclient.discovery import build

# Build calendar service (same credentials as Gmail)
calendar = build(
    'calendar', 'v3',
    credentials=creds,
    cache_discovery=False
)

# Get a list of the user's calendars
cal_list = calendar.calendarList().list().execute()
for cal in cal_list.get('items', []):
    print(f'{cal["summary"]}: {cal["id"]}')
    # Primary calendar ID is the user's email address

سرد الأحداث القادمة

استخدم service.events().list() لاسترداد الأحداث. وتُستخدم المعلَمتان timeMin وtimeMax لتصفية الأحداث حسب النطاق الزمني. استخدم دائمًا سلاسل تاريخ ووقت بتنسيق RFC 3339 مع إزاحة المنطقة الزمنية. اضبط singleEvents=True لتوسيع الأحداث المتكررة إلى مثيلات فردية.

import datetime
import pytz

def get_upcoming_events(service, calendar_id='primary', max_results=10):
    now = datetime.datetime.now(pytz.utc)
    time_min = now.isoformat()  # RFC 3339 format
    time_max = (now + datetime.timedelta(days=7)).isoformat()

    events_result = service.events().list(
        calendarId=calendar_id,
        timeMin=time_min,
        timeMax=time_max,
        maxResults=max_results,
        singleEvents=True,      # expand recurring events
        orderBy='startTime'
    ).execute()

    events = events_result.get('items', [])
    for event in events:
        start = event['start'].get('dateTime', event['start'].get('date'))
        print(f'{start}: {event["summary"]}')

    return events

تحليل أوقات بدء الأحداث وانتهائها

للأحداث في التقويم نوعان من الوقت: dateTime (وقت محدد مع المنطقة الزمنية) للأحداث العادية، وdate (التاريخ فقط، من دون وقت) للأحداث التي تستمر طوال اليوم. تحقّق دائمًا من الحقل الموجود قبل إجراء التحليل.

from datetime import datetime
import re

def parse_event_time(time_dict):
    if 'dateTime' in time_dict:
        # Parse RFC 3339 datetime: '2026-05-29T14:00:00+03:00'
        dt_str = time_dict['dateTime']
        # Python 3.7+ fromisoformat handles this
        return datetime.fromisoformat(dt_str), False  # not all-day
    else:
        # All-day event: '2026-05-29'
        date_str = time_dict['date']
        return datetime.strptime(date_str, '%Y-%m-%d'), True  # all-day

for event in events:
    start_dt, is_all_day = parse_event_time(event['start'])
    end_dt, _ = parse_event_time(event['end'])
    duration = end_dt - start_dt if not is_all_day else None
    print(f'{event["summary"]}: {start_dt.strftime("%H:%M")} '
          f'({"all-day" if is_all_day else str(duration)})')

إنشاء حدث بسيط

استخدم service.events().insert() لإنشاء حدث جديد. والحقول المطلوبة بالحد الأدنى هي summary (العنوان) وstart وend. يجب أن تكون الأوقات بتنسيق RFC 3339 مع المنطقة الزمنية. ويحدد الحقل timeZone في start/end اسم المنطقة الزمنية.

def create_event(service, title, start_datetime, end_datetime,
                 description='', timezone='UTC', calendar_id='primary'):
    event = {
        'summary': title,
        'description': description,
        'start': {
            'dateTime': start_datetime.isoformat(),
            'timeZone': timezone
        },
        'end': {
            'dateTime': end_datetime.isoformat(),
            'timeZone': timezone
        }
    }

    created = service.events().insert(
        calendarId=calendar_id,
        body=event
    ).execute()

    print(f'Event created: {created["summary"]}')
    print(f'Event ID: {created["id"]}')
    print(f'Link: {created["htmlLink"]}')
    return created

# --- demo: minimal stand-in for the Calendar API's service object ---
import datetime

class _Exec:
    def __init__(self, result):
        self._result = result
    def execute(self):
        return self._result

class _FakeEvents:
    def insert(self, calendarId, body):
        return _Exec({**body, 'id': 'evt_123',
                       'htmlLink': 'https://calendar.google.com/event?eid=evt_123'})

class _FakeService:
    def events(self):
        return _FakeEvents()

service = _FakeService()
start = datetime.datetime(2026, 8, 10, 9, 0)
end = start + datetime.timedelta(hours=1)
create_event(service, 'Team Sync', start, end, description='Weekly sync')

إضافة الحاضرين إلى الأحداث

أضف الحاضرين إلى الحدث من خلال تضمين قائمة attendees التي تحتوي على عناوين البريد الإلكتروني. اضبط sendUpdates='all' لإرسال دعوات Google Calendar تلقائيًا إلى جميع الحاضرين. استخدم 'externalOnly' لإشعار الضيوف الخارجيين فقط.

import datetime

def schedule_meeting(service, title, start_iso, duration_minutes,
                     attendees, description=''):
    start = datetime.datetime.fromisoformat(start_iso)
    end = start + datetime.timedelta(minutes=duration_minutes)

    event = {
        'summary': title,
        'description': description,
        'start': {'dateTime': start.isoformat(), 'timeZone': 'UTC'},
        'end': {'dateTime': end.isoformat(), 'timeZone': 'UTC'},
        'attendees': [
            {'email': email} for email in attendees
        ],
        'conferenceData': {
            'createRequest': {'requestId': f'meet-{start.timestamp()}'}
        }  # creates a Google Meet link
    }

    created = service.events().insert(
        calendarId='primary',
        body=event,
        sendUpdates='all',           # send invites
        conferenceDataVersion=1      # enable Meet link creation
    ).execute()
    return created

# --- demo: minimal stand-in for the Calendar API's service object ---
class _Exec:
    def __init__(self, result):
        self._result = result
    def execute(self):
        return self._result

class _FakeEvents:
    def insert(self, calendarId, body, sendUpdates=None, conferenceDataVersion=None):
        return _Exec({**body, 'id': 'evt_456'})

class _FakeService:
    def events(self):
        return _FakeEvents()

service = _FakeService()
created = schedule_meeting(
    service, 'Sprint Planning', '2026-08-11T10:00:00', 30,
    attendees=['alice@example.com', 'bob@example.com']
)
print(f'Meeting scheduled: {created["summary"]}')
print(f'Attendees: {[a["email"] for a in created["attendees"]]}')

إضافة التذكيرات إلى الأحداث

يمكن أن تتضمن الأحداث التذكيرات — وهي إشعارات تُرسل قبل الحدث. استخدم 'popup' لإشعارات المتصفح أو التطبيق، و'email' لتذكيرات البريد الإلكتروني. اضبط useDefault: False لتجاوز إعدادات التقويم الافتراضية باستخدام توقيتات مخصصة.

def create_event_with_reminders(service, title, start_iso, end_iso):
    event = {
        'summary': title,
        'start': {'dateTime': start_iso, 'timeZone': 'UTC'},
        'end': {'dateTime': end_iso, 'timeZone': 'UTC'},
        'reminders': {
            'useDefault': False,
            'overrides': [
                {'method': 'email', 'minutes': 24 * 60},   # 1 day before
                {'method': 'popup', 'minutes': 30},         # 30 min before
                {'method': 'popup', 'minutes': 10}          # 10 min before
            ]
        }
    }

    return service.events().insert(
        calendarId='primary',
        body=event
    ).execute()

# --- demo: minimal stand-in for the Calendar API's service object ---
class _Exec:
    def __init__(self, result):
        self._result = result
    def execute(self):
        return self._result

class _FakeEvents:
    def insert(self, calendarId, body):
        return _Exec({**body, 'id': 'evt_789'})

class _FakeService:
    def events(self):
        return _FakeEvents()

service = _FakeService()
created = create_event_with_reminders(
    service, 'Deploy Review', '2026-08-12T15:00:00', '2026-08-12T15:30:00'
)
print(f'Event id: {created["id"]}')
print('Reminders:', created['reminders']['overrides'])

إنشاء أحداث متكررة

تستخدم الأحداث المتكررة سلسلة RRULE (قاعدة التكرار) — وهي بالتنسيق نفسه المستخدم في iCalendar RFC 5545. ومن القواعد الشائعة: FREQ=WEEKLY;BYDAY=MO,WE,FR لأيام الاثنين والأربعاء والجمعة، وFREQ=MONTHLY;BYDAY=1MO لأول يوم اثنين من كل شهر.

def create_recurring_event(service, title, start_iso, end_iso,
                           rrule, timezone='UTC'):
    event = {
        'summary': title,
        'start': {'dateTime': start_iso, 'timeZone': timezone},
        'end': {'dateTime': end_iso, 'timeZone': timezone},
        'recurrence': [
            f'RRULE:{rrule}'  # recurrence rule string
        ]
    }

    return service.events().insert(
        calendarId='primary',
        body=event
    ).execute()

# Weekly team standup every Monday at 9am for 30 min
create_recurring_event(
    service=calendar_service,
    title='Team Standup',
    start_iso='2026-06-01T09:00:00',
    end_iso='2026-06-01T09:30:00',
    rrule='FREQ=WEEKLY;BYDAY=MO;COUNT=52',  # 52 weeks
    timezone='America/New_York'
)

تحديث حدث موجود

استخدم service.events().patch() لتحديث حقول محددة في حدث موجود من دون استبدال الحدث بأكمله. استخدم .update() لاستبدال نص الحدث بالكامل. ويتطلب كلاهما معرّف الحدث الوارد في الاستجابة الأصلية لـ create أو list.

def reschedule_event(service, event_id, new_start_iso, new_end_iso,
                     timezone='UTC', calendar_id='primary'):
    updated_fields = {
        'start': {'dateTime': new_start_iso, 'timeZone': timezone},
        'end': {'dateTime': new_end_iso, 'timeZone': timezone}
    }

    updated_event = service.events().patch(
        calendarId=calendar_id,
        eventId=event_id,
        body=updated_fields,
        sendUpdates='all'  # notify attendees of the change
    ).execute()

    print(f'Event rescheduled: {updated_event["summary"]}')
    print(f'New start: {updated_event["start"]["dateTime"]}')
    return updated_event

# --- demo: minimal stand-in for the Calendar API's service object ---
class _Exec:
    def __init__(self, result):
        self._result = result
    def execute(self):
        return self._result

class _FakeEvents:
    def patch(self, calendarId, eventId, body, sendUpdates=None):
        return _Exec({'summary': 'Team Sync', 'id': eventId, **body})

class _FakeService:
    def events(self):
        return _FakeEvents()

service = _FakeService()
reschedule_event(service, 'evt_123', '2026-08-13T09:00:00', '2026-08-13T10:00:00')

حذف الأحداث

استخدم service.events().delete() لإلغاء الحدث وإزالته. يؤدي ضبط sendUpdates='all' إلى إشعار الحاضرين. وبالنسبة إلى الأحداث المتكررة، يمكنك حذف مثيل واحد أو السلسلة بأكملها، وفقًا لمعرّف الحدث المستخدم.

from googleapiclient.errors import HttpError

def cancel_event(service, event_id, notify_attendees=True,
                 calendar_id='primary'):
    try:
        service.events().delete(
            calendarId=calendar_id,
            eventId=event_id,
            sendUpdates='all' if notify_attendees else 'none'
        ).execute()
        print(f'Event {event_id} cancelled')
        return True
    except HttpError as e:
        if e.resp.status == 404:
            print(f'Event {event_id} not found (already deleted?)')
        elif e.resp.status == 403:
            print('No permission to delete this event')
        else:
            print(f'Delete failed: {e.resp.status}')
        return False

التحقق من التوافر ووقت الانشغال

قبل جدولة اجتماع، تحقّق من توافر الحاضرين باستخدام واجهة برمجة التطبيقات freebusy. فهي تُرجع فترات الانشغال لقائمة من التقويمات ضمن نافذة زمنية محددة، ما يجعلها مناسبة تمامًا للعثور على أوقات متاحة لوكلاء الجدولة.

import datetime
import pytz

def check_availability(service, attendees, duration_hours=1):
    now = datetime.datetime.now(pytz.utc)
    time_min = now.isoformat()
    time_max = (now + datetime.timedelta(days=5)).isoformat()

    body = {
        'timeMin': time_min,
        'timeMax': time_max,
        'timeZone': 'UTC',
        'items': [{'id': email} for email in attendees]
    }

    result = service.freebusy().query(body=body).execute()

    for email in attendees:
        busy_slots = result['calendars'].get(email, {}).get('busy', [])
        print(f'{email}: {len(busy_slots)} busy slots in next 5 days')
        for slot in busy_slots[:3]:
            print(f'  Busy: {slot["start"]} -> {slot["end"]}')

    return result

البحث عن الأحداث باستخدام استعلام

استخدم المعلَمة q في events().list() للبحث عن الأحداث نصيًا — إذ يشمل البحث العنوان والوصف والموقع وأسماء الحاضرين. ادمجها مع timeMin/timeMax لحصر النتائج ضمن فترة محددة.

def search_events(service, query, days_back=30, days_forward=30,
                  calendar_id='primary'):
    import datetime, pytz
    now = datetime.datetime.now(pytz.utc)

    result = service.events().list(
        calendarId=calendar_id,
        q=query,
        timeMin=(now - datetime.timedelta(days=days_back)).isoformat(),
        timeMax=(now + datetime.timedelta(days=days_forward)).isoformat(),
        singleEvents=True,
        orderBy='startTime',
        maxResults=50
    ).execute()

    events = result.get('items', [])
    print(f'Found {len(events)} events matching "{query}"')
    for event in events:
        start = event['start'].get('dateTime', event['start'].get('date'))
        print(f'  {start}: {event["summary"]}')
    return events

تحقق سريع: المعلَمة singleEvents

اختبر مدى فهمك لواجهة Calendar API.

مراجعة Calendar API

يمكن لوكلائك الآن إدارة Google Calendar برمجيًا:

  • سرد الأحداث: events().list(timeMin=now, singleEvents=True, orderBy='startTime')
  • إنشاء الأحداث: events().insert(body={summary, start, end, attendees})
  • الأحداث المتكررة: أضف recurrence: ['RRULE:FREQ=WEEKLY;BYDAY=MO']
  • التذكيرات: استخدم reminders.overrides مع method: popup/email وminutes
  • التحديث: استخدم events().patch() للتحديثات الجزئية، وsendUpdates='all' لإشعار الحاضرين
  • التوافر والانشغال: استخدم freebusy().query() للتحقق من التوافر قبل الجدولة
البدء مجانًا

تعلم AI Agents مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
60
الدروس
239

الأسئلة الشائعة

هل درس «إنشاء أحداث التقويم والاستعلام عنها» مجاني؟

نعم — نص درس «إنشاء أحداث التقويم والاستعلام عنها» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Agents، انتقل إلى CoddyKit PRO. تتضمن دورة AI Agents 4 دروس في المجموع.

ماذا ستتعلم في «إنشاء أحداث التقويم والاستعلام عنها»؟

Google Calendar API: عرض الأحداث، وإنشاء الاجتماعات، وضبط التذكيرات تتمرن على AI Agents مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ AI Agents؟

لا تُشترط خبرة سابقة. AI Agents على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «إنشاء أحداث التقويم والاستعلام عنها»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس AI Agents هذا؟

نعم. كل درس في AI Agents يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الاتصال بـ Gmail عبر API
  2. قراءة رسائل البريد وإرسالها برمجيًا
  3. إنشاء أحداث التقويم والاستعلام عنها
  4. بناء وكيل مساعد بسيط للبريد الإلكتروني
← العودة إلى AI Agents