إنشاء أحداث

لنفترض أنّك تصمّم تطبيقًا يساعد المستخدمين في العثور على أفضل مسارات التنزّه. من خلال إضافة خطة التنزه كحدث في التقويم، يحصل المستخدمون على الكثير من المساعدة في البقاء منظَّمين تلقائيًا. يساعدهم "تقويم Google" في مشاركة الخطة وتذكيرهم بها حتى يتمكّنوا من الاستعداد بدون أي ضغط. وبفضل التكامل السلس لمنتجات Google، يرسل Google Now إشعارات إلى المستخدمين بشأن وقت المغادرة، وتوجّههم "خرائط Google" إلى مكان الاجتماع في الوقت المحدد.

توضّح هذه المقالة كيفية إنشاء أحداث في التقويم وإضافتها إلى تقاويم المستخدمين.

إضافة حدث

لإنشاء حدث، استدعِ طريقة events.insert() مع توفير المَعلمات التالية على الأقل:

  • calendarId هو معرّف التقويم ويمكن أن يكون إما عنوان البريد الإلكتروني للتقويم الذي سيتم إنشاء الحدث فيه أو كلمة رئيسية خاصة 'primary' سيتم استخدام التقويم الأساسي للمستخدم الذي سجّل الدخول. إذا كنت لا تعرف عنوان البريد الإلكتروني للتقويم الذي تريد استخدامه، يمكنك التحقّق منه إما في إعدادات التقويم ضمن واجهة مستخدم الويب في "تقويم Google" (في القسم "عنوان التقويم") أو يمكنك البحث عنه في نتيجة طلب calendarList.list().
  • event هو الحدث الذي سيتم إنشاؤه مع كل التفاصيل اللازمة، مثل وقت البدء والانتهاء. الحقلان المطلوبان الوحيدان هما وقت start ووقت end. راجِع مرجع event للاطّلاع على المجموعة الكاملة من حقول الأحداث.

لإنشاء أحداث بنجاح، عليك اتّباع الخطوات التالية:

  • اضبط نطاق OAuth على https://www.googleapis.com/auth/calendar حتى تتمكّن من تعديل تقويم المستخدم.
  • تأكَّد من أنّ المستخدم الذي تمت المصادقة عليه لديه إذن تعديل التقويم باستخدام calendarId الذي قدّمته (على سبيل المثال، من خلال طلب calendarList.get() للحصول على calendarId والتحقّق من accessRole).

إضافة البيانات الوصفية للأحداث

يمكنك اختياريًا إضافة بيانات وصفية للحدث عند إنشاء حدث في التقويم. إذا اخترت عدم إضافة بيانات وصفية أثناء عملية الإنشاء، يمكنك تعديل العديد من الحقول باستخدام events.update()، ولكن لا يمكن ضبط بعض الحقول، مثل معرّف الحدث، إلا أثناء عملية events.insert().

الموقع الجغرافي
تتيح إضافة عنوان في حقل الموقع الجغرافي استخدام ميزات مثل "وقت المغادرة" أو عرض خريطة تتضمّن الاتجاهات.
رقم تعريف الحدث
عند إنشاء حدث، يمكنك اختيار إنشاء معرّف الحدث الخاص بك الذي يتوافق مع متطلبات التنسيق. يتيح لك ذلك إبقاء العناصر في قاعدة البيانات المحلية متزامنة مع الأحداث في "تقويم Google". ويمنع أيضًا إنشاء أحداث مكرّرة إذا تعذّرت العملية في مرحلة ما بعد تنفيذها بنجاح في الخلفية الخاصة بـ "تقويم Google". في حال عدم توفير معرّف حدث، سينشئ الخادم معرّفًا لك. راجِع مرجع معرّف الحدث للحصول على مزيد من المعلومات.
الحضور
يظهر الحدث الذي تنشئه في جميع تقاويم Google الأساسية الخاصة بالضيوف الذين أضفتهم مع معرّف الحدث نفسه. إذا ضبطت sendUpdates على "all" أو "externalOnly" في طلب الإدراج، سيتلقّى الضيوف المعنيون إشعارًا عبر البريد الإلكتروني بشأن الحدث. لمزيد من المعلومات، اطّلِع على الأحداث التي تضمّ عدة ضيوف.

توضّح الأمثلة التالية كيفية إنشاء حدث وضبط بياناته الوصفية:

انتقال

// Refer to the Go quickstart on how to setup the environment:
// https://developers.google.com/workspace/calendar/quickstart/go
// Change the scope to calendar.CalendarScope and delete any stored credentials.

event := &calendar.Event{
  Summary: "Google I/O 2015",
  Location: "800 Howard St., San Francisco, CA 94103",
  Description: "A chance to hear more about Google's developer products.",
  Start: &calendar.EventDateTime{
    DateTime: "2015-05-28T09:00:00-07:00",
    TimeZone: "America/Los_Angeles",
  },
  End: &calendar.EventDateTime{
    DateTime: "2015-05-28T17:00:00-07:00",
    TimeZone: "America/Los_Angeles",
  },
  Recurrence: []string{"RRULE:FREQ=DAILY;COUNT=2"},
  Attendees: []*calendar.EventAttendee{
    &calendar.EventAttendee{Email:"lpage@example.com"},
    &calendar.EventAttendee{Email:"sbrin@example.com"},
  },
}

calendarId := "primary"
event, err = srv.Events.Insert(calendarId, event).Do()
if err != nil {
  log.Fatalf("Unable to create event. %v\n", err)
}
fmt.Printf("Event created: %s\n", event.HtmlLink)

Java

// Refer to the Java quickstart on how to setup the environment:
// https://developers.google.com/workspace/calendar/quickstart/java
// Change the scope to CalendarScopes.CALENDAR and delete any stored
// credentials.

Event event = new Event()
    .setSummary("Google I/O 2015")
    .setLocation("800 Howard St., San Francisco, CA 94103")
    .setDescription("A chance to hear more about Google's developer products.");

DateTime startDateTime = new DateTime("2015-05-28T09:00:00-07:00");
EventDateTime start = new EventDateTime()
    .setDateTime(startDateTime)
    .setTimeZone("America/Los_Angeles");
event.setStart(start);

DateTime endDateTime = new DateTime("2015-05-28T17:00:00-07:00");
EventDateTime end = new EventDateTime()
    .setDateTime(endDateTime)
    .setTimeZone("America/Los_Angeles");
event.setEnd(end);

String[] recurrence = new String[] {"RRULE:FREQ=DAILY;COUNT=2"};
event.setRecurrence(Arrays.asList(recurrence));

EventAttendee[] attendees = new EventAttendee[] {
    new EventAttendee().setEmail("lpage@example.com"),
    new EventAttendee().setEmail("sbrin@example.com"),
};
event.setAttendees(Arrays.asList(attendees));

EventReminder[] reminderOverrides = new EventReminder[] {
    new EventReminder().setMethod("email").setMinutes(24 * 60),
    new EventReminder().setMethod("popup").setMinutes(10),
};
Event.Reminders reminders = new Event.Reminders()
    .setUseDefault(false)
    .setOverrides(Arrays.asList(reminderOverrides));
event.setReminders(reminders);

String calendarId = "primary";
event = service.events().insert(calendarId, event).execute();
System.out.printf("Event created: %s\n", event.getHtmlLink());

JavaScript

// Refer to the JavaScript quickstart on how to setup the environment:
// https://developers.google.com/workspace/calendar/quickstart/js
// Change the scope to 'https://www.googleapis.com/auth/calendar' and delete any
// stored credentials.

const event = {
  'summary': 'Google I/O 2015',
  'location': '800 Howard St., San Francisco, CA 94103',
  'description': 'A chance to hear more about Google\'s developer products.',
  'start': {
    'dateTime': '2015-05-28T09:00:00-07:00',
    'timeZone': 'America/Los_Angeles'
  },
  'end': {
    'dateTime': '2015-05-28T17:00:00-07:00',
    'timeZone': 'America/Los_Angeles'
  },
  'recurrence': [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  'attendees': [
    {'email': 'lpage@example.com'},
    {'email': 'sbrin@example.com'}
  ],
  'reminders': {
    'useDefault': false,
    'overrides': [
      {'method': 'email', 'minutes': 24 * 60},
      {'method': 'popup', 'minutes': 10}
    ]
  }
};

const request = gapi.client.calendar.events.insert({
  'calendarId': 'primary',
  'resource': event
});

request.execute(function(event) {
  appendPre('Event created: ' + event.htmlLink);
});

Node.js

// Refer to the Node.js quickstart on how to setup the environment:
// https://developers.google.com/workspace/calendar/quickstart/node
// Change the scope to 'https://www.googleapis.com/auth/calendar' and delete any
// stored credentials.

const event = {
  'summary': 'Google I/O 2015',
  'location': '800 Howard St., San Francisco, CA 94103',
  'description': 'A chance to hear more about Google\'s developer products.',
  'start': {
    'dateTime': '2015-05-28T09:00:00-07:00',
    'timeZone': 'America/Los_Angeles',
  },
  'end': {
    'dateTime': '2015-05-28T17:00:00-07:00',
    'timeZone': 'America/Los_Angeles',
  },
  'recurrence': [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  'attendees': [
    {'email': 'lpage@example.com'},
    {'email': 'sbrin@example.com'},
  ],
  'reminders': {
    'useDefault': false,
    'overrides': [
      {'method': 'email', 'minutes': 24 * 60},
      {'method': 'popup', 'minutes': 10},
    ],
  },
};

calendar.events.insert({
  auth: auth,
  calendarId: 'primary',
  resource: event,
}, function(err, event) {
  if (err) {
    console.log('There was an error contacting the Calendar service: ' + err);
    return;
  }
  console.log('Event created: %s', event.htmlLink);
});

PHP

$event = new Google_Service_Calendar_Event(array(
  'summary' => 'Google I/O 2015',
  'location' => '800 Howard St., San Francisco, CA 94103',
  'description' => 'A chance to hear more about Google\'s developer products.',
  'start' => array(
    'dateTime' => '2015-05-28T09:00:00-07:00',
    'timeZone' => 'America/Los_Angeles',
  ),
  'end' => array(
    'dateTime' => '2015-05-28T17:00:00-07:00',
    'timeZone' => 'America/Los_Angeles',
  ),
  'recurrence' => array(
    'RRULE:FREQ=DAILY;COUNT=2'
  ),
  'attendees' => array(
    array('email' => 'lpage@example.com'),
    array('email' => 'sbrin@example.com'),
  ),
  'reminders' => array(
    'useDefault' => FALSE,
    'overrides' => array(
      array('method' => 'email', 'minutes' => 24 * 60),
      array('method' => 'popup', 'minutes' => 10),
    ),
  ),
));

$calendarId = 'primary';
$event = $service->events->insert($calendarId, $event);
printf('Event created: %s\n', $event->htmlLink);

Python

# Refer to the Python quickstart on how to setup the environment:
# https://developers.google.com/workspace/calendar/quickstart/python
# Change the scope to 'https://www.googleapis.com/auth/calendar' and delete any
# stored credentials.

event = {
  'summary': 'Google I/O 2015',
  'location': '800 Howard St., San Francisco, CA 94103',
  'description': 'A chance to hear more about Google\'s developer products.',
  'start': {
    'dateTime': '2015-05-28T09:00:00-07:00',
    'timeZone': 'America/Los_Angeles',
  },
  'end': {
    'dateTime': '2015-05-28T17:00:00-07:00',
    'timeZone': 'America/Los_Angeles',
  },
  'recurrence': [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  'attendees': [
    {'email': 'lpage@example.com'},
    {'email': 'sbrin@example.com'},
  ],
  'reminders': {
    'useDefault': False,
    'overrides': [
      {'method': 'email', 'minutes': 24 * 60},
      {'method': 'popup', 'minutes': 10},
    ],
  },
}

event = service.events().insert(calendarId='primary', body=event).execute()
print 'Event created: %s' % (event.get('htmlLink'))

Ruby

event = Google::Apis::CalendarV3::Event.new(
  summary: 'Google I/O 2015',
  location: '800 Howard St., San Francisco, CA 94103',
  description: 'A chance to hear more about Google\'s developer products.',
  start: Google::Apis::CalendarV3::EventDateTime.new(
    date_time: '2015-05-28T09:00:00-07:00',
    time_zone: 'America/Los_Angeles'
  ),
  end: Google::Apis::CalendarV3::EventDateTime.new(
    date_time: '2015-05-28T17:00:00-07:00',
    time_zone: 'America/Los_Angeles'
  ),
  recurrence: [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  attendees: [
    Google::Apis::CalendarV3::EventAttendee.new(
      email: 'lpage@example.com'
    ),
    Google::Apis::CalendarV3::EventAttendee.new(
      email: 'sbrin@example.com'
    )
  ],
  reminders: Google::Apis::CalendarV3::Event::Reminders.new(
    use_default: false,
    overrides: [
      Google::Apis::CalendarV3::EventReminder.new(
        reminder_method: 'email',
        minutes: 24 * 60
      ),
      Google::Apis::CalendarV3::EventReminder.new(
        reminder_method: 'popup',
        minutes: 10
      )
    ]
  )
)

result = client.insert_event('primary', event)
puts "Event created: #{result.html_link}"

إضافة مرفقات Drive إلى الأحداث

يمكنك إرفاق ملفات Google Drive، مثل ملاحظات الاجتماع في "مستندات Google" أو الميزانيات في "جداول بيانات Google" أو العروض التقديمية في "العروض التقديمية من Google" أو أي ملفات أخرى ذات صلة في Google Drive بأحداث التقويم. يمكنك إضافة المرفق عند إنشاء حدث باستخدام events.insert() أو لاحقًا كجزء من تعديل، مثل events.patch()

يتضمّن إرفاق ملف Google Drive بحدث خطوتَين:

  1. احصل على عنوان URL للملف alternateLink وtitle وmimeType من مورد ملفات Drive API، عادةً باستخدام طريقة files.get().
  2. أنشئ حدثًا أو عدِّله باستخدام حقول attachments التي تم ضبطها في نص الطلب، مع ضبط المَعلمة supportsAttachments على true.

يوضّح مثال الرمز البرمجي التالي كيفية تعديل حدث حالي لإضافة مرفق:

Java

public static void addAttachment(Calendar calendarService, Drive driveService, String calendarId,
    String eventId, String fileId) throws IOException {
  File file = driveService.files().get(fileId).execute();
  Event event = calendarService.events().get(calendarId, eventId).execute();

  List<EventAttachment> attachments = event.getAttachments();
  if (attachments == null) {
    attachments = new ArrayList<EventAttachment>();
  }
  attachments.add(new EventAttachment()
      .setFileUrl(file.getAlternateLink())
      .setMimeType(file.getMimeType())
      .setTitle(file.getTitle()));

  Event changes = new Event()
      .setAttachments(attachments);
  calendarService.events().patch(calendarId, eventId, changes)
      .setSupportsAttachments(true)
      .execute();
}

PHP

function addAttachment($calendarService, $driveService, $calendarId, $eventId, $fileId) {
  $file = $driveService->files->get($fileId);
  $event = $calendarService->events->get($calendarId, $eventId);
  $attachments = $event->attachments;

  $attachments[] = array(
    'fileUrl' => $file->alternateLink,
    'mimeType' => $file->mimeType,
    'title' => $file->title
  );
  $changes = new Google_Service_Calendar_Event(array(
    'attachments' => $attachments
  ));

  $calendarService->events->patch($calendarId, $eventId, $changes, array(
    'supportsAttachments' => TRUE
  ));
}

Python

def add_attachment(calendarService, driveService, calendarId, eventId, fileId):
    file = driveService.files().get(fileId=fileId).execute()
    event = calendarService.events().get(calendarId=calendarId,
                                         eventId=eventId).execute()

    attachments = event.get('attachments', [])
    attachments.append({
        'fileUrl': file['alternateLink'],
        'mimeType': file['mimeType'],
        'title': file['title']
    })

    changes = {
        'attachments': attachments
    }
    calendarService.events().patch(calendarId=calendarId, eventId=eventId,
                                   body=changes,
                                   supportsAttachments=True).execute()

إضافة مؤتمرات فيديو ومؤتمرات هاتف إلى الأحداث

يمكنك ربط الأحداث بمؤتمرات Hangouts وGoogle Meet للسماح للمستخدمين بعقد اجتماعات عن بُعد من خلال مكالمة هاتفية أو مكالمة فيديو.

يمكن استخدام الحقل conferenceData لقراءة تفاصيل الاجتماع الحالية ونسخها ومحوها، ويمكن أيضًا استخدامه لطلب إنشاء اجتماعات جديدة. للسماح بإنشاء تفاصيل الاجتماع وتعديلها، اضبط مَعلمة الطلب conferenceDataVersion على 1.

تتوفّر حاليًا ثلاثة أنواع من conferenceData، كما هو موضّح في conferenceData.conferenceSolution.key.type:

  1. ‫Hangouts للمستهلكين (eventHangout)
  2. ‫Hangouts الكلاسيكي Google Workspace للمستخدمين (تم إيقافه نهائيًا؛ eventNamedHangout)
  3. ‫Google Meet (hangoutsMeet)

يمكنك معرفة نوع الاجتماع المتوافق مع أي تقويم لمستخدم معيّن من خلال البحث عن conferenceProperties.allowedConferenceSolutionTypes في مجموعتَي calendars وcalendarList. يمكنك أيضًا معرفة ما إذا كان المستخدم يفضّل إنشاء اجتماعات Hangouts لجميع الأحداث التي ينشئها حديثًا من خلال التحقّق من إعداد autoAddHangouts في مجموعة settings.

بالإضافة إلى type، يوفّر conferenceSolution أيضًا الحقلين name وiconUri اللذين يمكنك استخدامهما لتمثيل حل المؤتمرات كما هو موضّح أدناه:

JavaScript

const solution = event.conferenceData.conferenceSolution;

const content = document.getElementById("content");
const text = document.createTextNode("Join " + solution.name);
const icon = document.createElement("img");
icon.src = solution.iconUri;

content.appendChild(icon);
content.appendChild(text);

يمكنك إنشاء اجتماع جديد لحدث من خلال تقديم createRequest مع requestId تم إنشاؤه حديثًا، ويمكن أن يكون string عشوائيًا. يتم إنشاء المؤتمرات بشكل غير متزامن، ولكن يمكنك دائمًا التحقّق من حالة طلبك لإعلام المستخدمين بما يحدث.

على سبيل المثال، لطلب إنشاء مكالمة فيديو لحدث حالي:

JavaScript

const eventPatch = {
  conferenceData: {
    createRequest: {requestId: "7qxalsvy0e"}
  }
};

gapi.client.calendar.events.patch({
  calendarId: "primary",
  eventId: "7cbh8rpc10lrc0ckih9tafss99",
  resource: eventPatch,
  sendUpdates: "all",
  conferenceDataVersion: 1
}).execute(function(event) {
  console.log("Conference created for event: %s", event.htmlLink);
});

قد لا تتضمّن الاستجابة الفورية لهذا الطلب conferenceData المكتمل بعد، ويتم الإشارة إلى ذلك من خلال رمز الحالة pending في الحقل الحالة. يتغيّر رمز الحالة إلى success بعد ملء معلومات المؤتمر. يحتوي الحقل entryPoints على معلومات حول معرّفات الموارد المنتظمة (URI) الخاصة بالفيديو والهاتف التي يمكن للمستخدمين الاتصال بها.

إذا أردت جدولة أحداث متعددة في "تقويم Google" باستخدام تفاصيل مكالمة فيديو نفسها، يمكنك نسخ conferenceData بالكامل من حدث إلى آخر.

تكون عملية النسخ مفيدة في حالات معيّنة. على سبيل المثال، لنفترض أنّك بصدد تطوير تطبيق توظيف يضبط أحداثًا منفصلة للمرشّح والمحاوِر، وتريد حماية هوية المحاوِر، ولكنك تريد أيضًا التأكّد من انضمام جميع المشاركين إلى مكالمة الفيديو نفسها.