feat: Add Composio Google Calendar component (#7662)
* feat: add google calendar component * feat: add Composio Google Calendar Component * fix: update field names to use '_' as separator & remove init * fix: update field names to use '_' as separator & remove init * feat: add google calendar test file & minor improvements * fix: format * fix: format --------- Co-authored-by: Edwin Jose <edwin.jose@datastax.com>
This commit is contained in:
parent
93e8b3e8c5
commit
2ea2bb01ed
9 changed files with 1020 additions and 0 deletions
|
|
@ -1,9 +1,11 @@
|
||||||
from .composio_api import ComposioAPIComponent
|
from .composio_api import ComposioAPIComponent
|
||||||
from .gmail_composio import ComposioGmailAPIComponent
|
from .gmail_composio import ComposioGmailAPIComponent
|
||||||
|
from .googlecalendar_composio import ComposioGoogleCalendarAPIComponent
|
||||||
from .slack_composio import ComposioSlackAPIComponent
|
from .slack_composio import ComposioSlackAPIComponent
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"ComposioAPIComponent",
|
"ComposioAPIComponent",
|
||||||
"ComposioGmailAPIComponent",
|
"ComposioGmailAPIComponent",
|
||||||
|
"ComposioGoogleCalendarAPIComponent",
|
||||||
"ComposioSlackAPIComponent",
|
"ComposioSlackAPIComponent",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,787 @@
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from composio import Action
|
||||||
|
|
||||||
|
from langflow.base.composio.composio_base import ComposioBaseComponent
|
||||||
|
from langflow.inputs import (
|
||||||
|
BoolInput,
|
||||||
|
IntInput,
|
||||||
|
MessageTextInput,
|
||||||
|
)
|
||||||
|
from langflow.logging import logger
|
||||||
|
|
||||||
|
|
||||||
|
class ComposioGoogleCalendarAPIComponent(ComposioBaseComponent):
|
||||||
|
"""Google Calendar API component for interacting with Google Calendar services."""
|
||||||
|
|
||||||
|
display_name: str = "Google Calendar"
|
||||||
|
description: str = "Google Calendar API"
|
||||||
|
icon = "Googlecalendar"
|
||||||
|
documentation: str = "https://docs.composio.dev"
|
||||||
|
app_name = "googlecalendar"
|
||||||
|
|
||||||
|
_actions_data: dict = {
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT": {
|
||||||
|
"display_name": "Update Google Event",
|
||||||
|
"action_fields": [
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_description",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_eventType",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_create_meeting_room",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_guestsCanSeeOtherGuests",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_guestsCanInviteOthers",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_location",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_summary",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_transparency",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_visibility",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_timezone",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_recurrence",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_guests_can_modify",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_attendees",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_send_updates",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_start_datetime",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_event_duration_hour",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_event_duration_minutes",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_calendar_id",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_event_id",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_REMOVE_ATTENDEE": {
|
||||||
|
"display_name": "Remove Attendee From Event",
|
||||||
|
"action_fields": [
|
||||||
|
"GOOGLECALENDAR_REMOVE_ATTENDEE_calendar_id",
|
||||||
|
"GOOGLECALENDAR_REMOVE_ATTENDEE_event_id",
|
||||||
|
"GOOGLECALENDAR_REMOVE_ATTENDEE_attendee_email",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_GET_CURRENT_DATE_TIME": {
|
||||||
|
"display_name": "Get Current Date And Time",
|
||||||
|
"action_fields": ["GOOGLECALENDAR_GET_CURRENT_DATE_TIME_timezone"],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_QUICK_ADD": {
|
||||||
|
"display_name": "Quick Add Event",
|
||||||
|
"action_fields": [
|
||||||
|
"GOOGLECALENDAR_QUICK_ADD_calendar_id",
|
||||||
|
"GOOGLECALENDAR_QUICK_ADD_text",
|
||||||
|
"GOOGLECALENDAR_QUICK_ADD_send_updates",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS": {
|
||||||
|
"display_name": "List Google Calendars",
|
||||||
|
"action_fields": [
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_max_results",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_min_access_role",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_page_token",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_show_deleted",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_show_hidden",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_sync_token",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT": {
|
||||||
|
"display_name": "Find Event",
|
||||||
|
"action_fields": [
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_calendar_id",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_query",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_max_results",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_order_by",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_show_deleted",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_single_events",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_timeMax",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_timeMin",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_updated_min",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_event_types",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_page_token",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT": {
|
||||||
|
"display_name": "Create Event",
|
||||||
|
"action_fields": [
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_description",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_eventType",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_create_meeting_room",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_guestsCanSeeOtherGuests",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_guestsCanInviteOthers",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_location",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_summary",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_transparency",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_visibility",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_timezone",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_recurrence",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_guests_can_modify",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_attendees",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_send_updates",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_start_datetime",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_event_duration_hour",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_event_duration_minutes",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_calendar_id",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_FIND_FREE_SLOTS": {
|
||||||
|
"display_name": "Find Free Slots",
|
||||||
|
"action_fields": [
|
||||||
|
"GOOGLECALENDAR_FIND_FREE_SLOTS_time_min",
|
||||||
|
"GOOGLECALENDAR_FIND_FREE_SLOTS_time_max",
|
||||||
|
"GOOGLECALENDAR_FIND_FREE_SLOTS_timezone",
|
||||||
|
"GOOGLECALENDAR_FIND_FREE_SLOTS_group_expansion_max",
|
||||||
|
"GOOGLECALENDAR_FIND_FREE_SLOTS_calendar_expansion_max",
|
||||||
|
"GOOGLECALENDAR_FIND_FREE_SLOTS_items",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_PATCH_CALENDAR": {
|
||||||
|
"display_name": "Patch Calendar",
|
||||||
|
"action_fields": [
|
||||||
|
"GOOGLECALENDAR_PATCH_CALENDAR_calendar_id",
|
||||||
|
"GOOGLECALENDAR_PATCH_CALENDAR_description",
|
||||||
|
"GOOGLECALENDAR_PATCH_CALENDAR_location",
|
||||||
|
"GOOGLECALENDAR_PATCH_CALENDAR_summary",
|
||||||
|
"GOOGLECALENDAR_PATCH_CALENDAR_timezone",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_GET_CALENDAR": {
|
||||||
|
"display_name": "Fetch Google Calendar",
|
||||||
|
"action_fields": ["GOOGLECALENDAR_GET_CALENDAR_calendar_id"],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_DELETE_EVENT": {
|
||||||
|
"display_name": "Delete Event",
|
||||||
|
"action_fields": ["GOOGLECALENDAR_DELETE_EVENT_calendar_id", "GOOGLECALENDAR_DELETE_EVENT_event_id"],
|
||||||
|
},
|
||||||
|
"GOOGLECALENDAR_DUPLICATE_CALENDAR": {
|
||||||
|
"display_name": "Duplicate Calendar",
|
||||||
|
"action_fields": ["GOOGLECALENDAR_DUPLICATE_CALENDAR_summary"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_list_variables = {
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_event_types",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_recurrence",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_attendees",
|
||||||
|
"GOOGLECALENDAR_FIND_FREE_SLOTS_items",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_recurrence",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_attendees",
|
||||||
|
}
|
||||||
|
|
||||||
|
_all_fields = {field for action_data in _actions_data.values() for field in action_data["action_fields"]}
|
||||||
|
_bool_variables = {
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_show_deleted",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_show_hidden",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_show_deleted",
|
||||||
|
"GOOGLECALENDAR_FIND_EVENT_single_events",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_create_meeting_room",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_guestsCanSeeOtherGuests",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_guestsCanInviteOthers",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_guests_can_modify",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_send_updates",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_create_meeting_room",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_guestsCanSeeOtherGuests",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_guestsCanInviteOthers",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_guests_can_modify",
|
||||||
|
"GOOGLECALENDAR_UPDATE_EVENT_send_updates",
|
||||||
|
}
|
||||||
|
|
||||||
|
inputs = [
|
||||||
|
*ComposioBaseComponent._base_inputs,
|
||||||
|
IntInput(
|
||||||
|
name="GOOGLECALENDAR_LIST_CALENDARS_max_results",
|
||||||
|
display_name="Max Results",
|
||||||
|
info="Maximum number of entries returned on one result page. The page size can never be larger than 250 entries.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
value=10,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_LIST_CALENDARS_min_access_role",
|
||||||
|
display_name="Min Access Role",
|
||||||
|
info="The minimum access role for the user in the returned entries. Accepted values are 'owner' & 'reader'",
|
||||||
|
show=False,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_LIST_CALENDARS_page_token",
|
||||||
|
display_name="Page Token",
|
||||||
|
info="Token specifying which result page to return.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_LIST_CALENDARS_show_deleted",
|
||||||
|
display_name="Show Deleted",
|
||||||
|
info="Whether to include deleted calendar list entries in the result.",
|
||||||
|
show=False,
|
||||||
|
value=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_LIST_CALENDARS_show_hidden",
|
||||||
|
display_name="Show Hidden",
|
||||||
|
info="Whether to show hidden entries.",
|
||||||
|
show=False,
|
||||||
|
value=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_LIST_CALENDARS_sync_token",
|
||||||
|
display_name="Sync Token",
|
||||||
|
info="Token obtained from the nextSyncToken field returned on the last page of results from the previous list request.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_calendar_id",
|
||||||
|
display_name="Calendar Id",
|
||||||
|
info="Identifier of the Google Calendar. Use 'primary' for the currently logged in user's primary calendar.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
value="primary",
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_query",
|
||||||
|
display_name="Query",
|
||||||
|
info="Search term to find events that match these terms in the event's summary, description, location, attendee's displayName, attendee's email, organizer's displayName, organizer's email, etc if needed.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
),
|
||||||
|
IntInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_max_results",
|
||||||
|
display_name="Max Results",
|
||||||
|
info="Maximum number of events returned on one result page. The page size can never be larger than 2500 events. The default value is 10.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
value=10,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_order_by",
|
||||||
|
display_name="Order By",
|
||||||
|
info="The order of the events returned in the result. Acceptable values are 'startTime' and 'updated'.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_show_deleted",
|
||||||
|
display_name="Show Deleted",
|
||||||
|
info="Whether to include deleted events (with status equals 'cancelled') in the result.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_single_events",
|
||||||
|
display_name="Single Events",
|
||||||
|
info="Whether to expand recurring events into instances and only return single one-off events and instances of recurring events, but not the underlying recurring events themselves.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
value=True,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_timeMax",
|
||||||
|
display_name="Timemax",
|
||||||
|
info="Upper bound (exclusive) for an event's start time to filter by. Accepts multiple formats:, 1. ISO format with timezone (e.g., 2024-12-06T13:00:00Z), 2. Comma-separated format (e.g., 2024,12,06,13,00,00), 3. Simple datetime format (e.g., 2024-12-06 13:00:00)", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_timeMin",
|
||||||
|
display_name="Timemin",
|
||||||
|
info="Lower bound (exclusive) for an event's end time to filter by. Accepts multiple formats:, 1. ISO format with timezone (e.g., 2024-12-06T13:00:00Z), 2. Comma-separated format (e.g., 2024,12,06,13,00,00), 3. Simple datetime format (e.g., 2024-12-06 13:00:00)", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_updated_min",
|
||||||
|
display_name="Updated Min",
|
||||||
|
info="Lower bound for an event's last modification time to filter by. Accepts multiple formats:, 1. ISO format with timezone (e.g., 2024-12-06T13:00:00Z), 2. Comma-separated format (e.g., 2024,12,06,13,00,00), 3. Simple datetime format (e.g., 2024-12-06 13:00:00)", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_event_types",
|
||||||
|
display_name="Event Types",
|
||||||
|
info="List of event types to return. Possible values are: default, outOfOffice, focusTime, workingLocation.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_EVENT_page_token",
|
||||||
|
display_name="Page Token",
|
||||||
|
info="Token specifying which result page to return. Optional.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_DUPLICATE_CALENDAR_summary",
|
||||||
|
display_name="Summary/Title",
|
||||||
|
info="Title of the calendar to be duplicated.",
|
||||||
|
show=False,
|
||||||
|
value="",
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_REMOVE_ATTENDEE_calendar_id",
|
||||||
|
display_name="Calendar Id",
|
||||||
|
info="ID of the Google Calendar",
|
||||||
|
show=False,
|
||||||
|
value="primary",
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_REMOVE_ATTENDEE_event_id",
|
||||||
|
display_name="Event Id",
|
||||||
|
info="ID of the event",
|
||||||
|
show=False,
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_REMOVE_ATTENDEE_attendee_email",
|
||||||
|
display_name="Attendee Email",
|
||||||
|
info="Email address of the attendee to be removed",
|
||||||
|
show=False,
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_GET_CALENDAR_calendar_id",
|
||||||
|
display_name="Calendar Id",
|
||||||
|
info="The ID of the Google Calendar that needs to be fetched. Default is 'primary'.",
|
||||||
|
show=False,
|
||||||
|
value="primary",
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_description",
|
||||||
|
display_name="Description",
|
||||||
|
info="Description of the event. Can contain HTML. Optional.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_eventType",
|
||||||
|
display_name="Event Type",
|
||||||
|
info="Type of the event, immutable post-creation. Currently, only 'default'",
|
||||||
|
show=False,
|
||||||
|
value="default",
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_create_meeting_room",
|
||||||
|
display_name="Create Meeting Room",
|
||||||
|
info="If true, a Google Meet link is created and added to the event.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_guestsCanSeeOtherGuests",
|
||||||
|
display_name="Guests Can See Other Guests",
|
||||||
|
info="Whether attendees other than the organizer can see who the event's attendees are.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_guestsCanInviteOthers",
|
||||||
|
display_name="Guests Can Invite Others",
|
||||||
|
info="Whether attendees other than the organizer can invite others to the event.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_location",
|
||||||
|
display_name="Location",
|
||||||
|
info="Geographic location of the event as free-form text.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_summary",
|
||||||
|
display_name="Summary/Title",
|
||||||
|
info="Summary (title) of the event.",
|
||||||
|
show=False,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_transparency",
|
||||||
|
display_name="Event Transparency",
|
||||||
|
info="'opaque' (busy) or 'transparent' (available).",
|
||||||
|
show=False,
|
||||||
|
value="opaque",
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_visibility",
|
||||||
|
display_name="Event Visibility",
|
||||||
|
info="Event visibility: 'default', 'public', 'private', or 'confidential'.",
|
||||||
|
show=False,
|
||||||
|
value="default",
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_timezone",
|
||||||
|
display_name="Timezone",
|
||||||
|
info="IANA timezone name (e.g., 'America/New_York'). Required if datetime is naive. If datetime includes timezone info (Z or offset), this field is optional and defaults to UTC.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_recurrence",
|
||||||
|
display_name="Recurrence",
|
||||||
|
info="List of RRULE, EXRULE, RDATE, EXDATE lines for recurring events.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_guests_can_modify",
|
||||||
|
display_name="Guests Can Modify",
|
||||||
|
info="If True, guests can modify the event.",
|
||||||
|
show=False,
|
||||||
|
value=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_attendees",
|
||||||
|
display_name="Attendees",
|
||||||
|
info="List of attendee emails (strings).",
|
||||||
|
show=False,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_send_updates",
|
||||||
|
display_name="Send Updates",
|
||||||
|
info="Defaults to True. Whether to send updates to the attendees.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_start_datetime",
|
||||||
|
display_name="Start Datetime",
|
||||||
|
info="Naive date/time (YYYY-MM-DDTHH:MM:SS) with NO offsets or Z. e.g. '2025-01-16T13:00:00'",
|
||||||
|
show=False,
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
IntInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_event_duration_hour",
|
||||||
|
display_name="Event Duration Hour",
|
||||||
|
info="Number of hours (0-24).",
|
||||||
|
show=False,
|
||||||
|
value=0,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
IntInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_event_duration_minutes",
|
||||||
|
display_name="Event Duration Minutes",
|
||||||
|
info="Number of minutes (0-59).",
|
||||||
|
show=False,
|
||||||
|
value=30,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_CREATE_EVENT_calendar_id",
|
||||||
|
display_name="Calendar Id",
|
||||||
|
info="The ID of the Google Calendar. `primary` for interacting with the primary calendar.",
|
||||||
|
show=False,
|
||||||
|
value="primary",
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_DELETE_EVENT_calendar_id",
|
||||||
|
display_name="Calendar Id",
|
||||||
|
info="ID of the Google Calendar",
|
||||||
|
show=False,
|
||||||
|
value="primary",
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_DELETE_EVENT_event_id",
|
||||||
|
display_name="Event Id",
|
||||||
|
info="ID of the event to be deleted",
|
||||||
|
show=False,
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_FREE_SLOTS_time_min",
|
||||||
|
display_name="Time Min",
|
||||||
|
info="The start datetime of the interval for the query. Supports multiple formats:, 1. ISO format with timezone (e.g., 2024-12-06T13:00:00Z), 2. Comma-separated format (e.g., 2024,12,06,13,00,00), 3. Simple datetime format (e.g., 2024-12-06 13:00:00)", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_FREE_SLOTS_time_max",
|
||||||
|
display_name="Time Max",
|
||||||
|
info="The end datetime of the interval for the query. Supports multiple formats:, 1. ISO format with timezone (e.g., 2024-12-06T13:00:00Z), 2. Comma-separated format (e.g., 2024,12,06,13,00,00), 3. Simple datetime format (e.g., 2024-12-06 13:00:00)", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_FREE_SLOTS_timezone",
|
||||||
|
display_name="Timezone",
|
||||||
|
info="Time zone used in the response. Optional. The default is UTC.",
|
||||||
|
show=False,
|
||||||
|
value="UTC",
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
IntInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_FREE_SLOTS_group_expansion_max",
|
||||||
|
display_name="Group Expansion Max",
|
||||||
|
info="Maximal number of calendar identifiers to be provided for a single group. Optional. An error is returned for a group with more members than this value. Maximum value is 100.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
value=100,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
IntInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_FREE_SLOTS_calendar_expansion_max",
|
||||||
|
display_name="Calendar Expansion Max",
|
||||||
|
info="Maximal number of calendars for which FreeBusy information is to be provided. Optional. Maximum value is 50.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
value=50,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_FIND_FREE_SLOTS_items",
|
||||||
|
display_name="Items",
|
||||||
|
info="List of calendars ids for which to fetch",
|
||||||
|
show=False,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_QUICK_ADD_calendar_id",
|
||||||
|
display_name="Calendar Id",
|
||||||
|
info="Calendar identifier. To list calendars to retrieve calendar IDs use relevant tools. To access the primary calendar of the currently logged in user, use the 'primary' keyword.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
value="primary",
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_QUICK_ADD_text",
|
||||||
|
display_name="Text",
|
||||||
|
info="The text describing the event to be created.",
|
||||||
|
show=False,
|
||||||
|
value="",
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_QUICK_ADD_send_updates",
|
||||||
|
display_name="Send Updates",
|
||||||
|
info="Guests who should receive notifications about the creation of the new event. Accepted fields include 'all', 'none', 'externalOnly'", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
value="none",
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_PATCH_CALENDAR_calendar_id",
|
||||||
|
display_name="Calendar Id",
|
||||||
|
info="The ID of the Google Calendar that needs to be updated.",
|
||||||
|
show=False,
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_PATCH_CALENDAR_description",
|
||||||
|
display_name="Description",
|
||||||
|
info="Description of the calendar. Optional.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_PATCH_CALENDAR_location",
|
||||||
|
display_name="Location",
|
||||||
|
info="Geographic location of the calendar as free-form text.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_PATCH_CALENDAR_summary",
|
||||||
|
display_name="Title/Summary",
|
||||||
|
info="Title of the calendar. This field is required and cannot be left blank as per the Google Calendar API requirements.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_PATCH_CALENDAR_timezone",
|
||||||
|
display_name="Timezone",
|
||||||
|
info="The time zone of the calendar. (Formatted as an IANA Time Zone Database name, e.g. 'Europe/Zurich').",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
IntInput(
|
||||||
|
name="GOOGLECALENDAR_GET_CURRENT_DATE_TIME_timezone",
|
||||||
|
display_name="Timezone",
|
||||||
|
info="The timezone offset from UTC to retrieve current date and time, like for location of UTC+6, you give 6, for UTC -9, your give -9.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
value=0,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_description",
|
||||||
|
display_name="Description",
|
||||||
|
info="Description of the event. Can contain HTML. Optional.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_eventType",
|
||||||
|
display_name="EventType",
|
||||||
|
info="Type of the event, immutable post-creation. Currently, only 'default' and 'workingLocation' can be created.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
value="default",
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_create_meeting_room",
|
||||||
|
display_name="Create Meeting Room",
|
||||||
|
info="If true, a Google Meet link is created and added to the event.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_guestsCanSeeOtherGuests",
|
||||||
|
display_name="Guests Can See Other Guests",
|
||||||
|
info="Whether attendees other than the organizer can see who the event's attendees are.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_guestsCanInviteOthers",
|
||||||
|
display_name="Guests Can Invite Others",
|
||||||
|
info="Whether attendees other than the organizer can invite others to the event.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_location",
|
||||||
|
display_name="Location",
|
||||||
|
info="Geographic location of the event as free-form text.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_summary",
|
||||||
|
display_name="Summary/Title",
|
||||||
|
info="Summary (title) of the event.",
|
||||||
|
show=False,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_transparency",
|
||||||
|
display_name="Event Transparency",
|
||||||
|
info="'opaque' (busy) or 'transparent' (available).",
|
||||||
|
show=False,
|
||||||
|
value="opaque",
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_visibility",
|
||||||
|
display_name="Event Visibility",
|
||||||
|
info="Event visibility: 'default', 'public', 'private', or 'confidential'.",
|
||||||
|
show=False,
|
||||||
|
value="default",
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_timezone",
|
||||||
|
display_name="Timezone",
|
||||||
|
info="IANA timezone name (e.g., 'America/New_York'). Required if datetime is naive. If datetime includes timezone info (Z or offset), this field is optional and defaults to UTC.", # noqa: E501
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_recurrence",
|
||||||
|
display_name="Recurrence",
|
||||||
|
info="List of RRULE, EXRULE, RDATE, EXDATE lines for recurring events.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_guests_can_modify",
|
||||||
|
display_name="Guests Can Modify",
|
||||||
|
info="If True, guests can modify the event.",
|
||||||
|
show=False,
|
||||||
|
value=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_attendees",
|
||||||
|
display_name="Attendees",
|
||||||
|
info="List of attendee emails (strings).",
|
||||||
|
show=False,
|
||||||
|
),
|
||||||
|
BoolInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_send_updates",
|
||||||
|
display_name="Send Updates",
|
||||||
|
info="Defaults to True. Whether to send updates to the attendees.",
|
||||||
|
show=False,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_start_datetime",
|
||||||
|
display_name="Start Datetime",
|
||||||
|
info="Naive date/time (YYYY-MM-DDTHH:MM:SS) with NO offsets or Z. e.g. '2025-01-16T13:00:00'",
|
||||||
|
show=False,
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
IntInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_event_duration_hour",
|
||||||
|
display_name="Event Duration Hour",
|
||||||
|
info="Number of hours (0-24).",
|
||||||
|
show=False,
|
||||||
|
value=0,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
IntInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_event_duration_minutes",
|
||||||
|
display_name="Event Duration Minutes",
|
||||||
|
info="Number of minutes (0-59).",
|
||||||
|
show=False,
|
||||||
|
value=30,
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_calendar_id",
|
||||||
|
display_name="Calendar Id",
|
||||||
|
info="ID of the Google Calendar",
|
||||||
|
show=False,
|
||||||
|
value="primary",
|
||||||
|
),
|
||||||
|
MessageTextInput(
|
||||||
|
name="GOOGLECALENDAR_UPDATE_EVENT_event_id",
|
||||||
|
display_name="Event Id",
|
||||||
|
info="ID of the event to be updated",
|
||||||
|
show=False,
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
def execute_action(self):
|
||||||
|
"""Execute action and return response as Message."""
|
||||||
|
toolset = self._build_wrapper()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._build_action_maps()
|
||||||
|
# Get the display name from the action list
|
||||||
|
display_name = self.action[0]["name"] if isinstance(self.action, list) and self.action else self.action
|
||||||
|
# Use the display_to_key_map to get the action key
|
||||||
|
action_key = self._display_to_key_map.get(display_name)
|
||||||
|
if not action_key:
|
||||||
|
msg = f"Invalid action: {display_name}"
|
||||||
|
raise ValueError(msg)
|
||||||
|
|
||||||
|
enum_name = getattr(Action, action_key)
|
||||||
|
params = {}
|
||||||
|
if action_key in self._actions_data:
|
||||||
|
for field in self._actions_data[action_key]["action_fields"]:
|
||||||
|
value = getattr(self, field)
|
||||||
|
|
||||||
|
if value is None or value == "":
|
||||||
|
continue
|
||||||
|
|
||||||
|
if field in self._list_variables and value:
|
||||||
|
value = [item.strip() for item in value.split(",")]
|
||||||
|
|
||||||
|
if field in self._bool_variables:
|
||||||
|
value = bool(value)
|
||||||
|
|
||||||
|
param_name = field.replace(action_key + "_", "")
|
||||||
|
params[param_name] = value
|
||||||
|
|
||||||
|
result = toolset.execute_action(
|
||||||
|
action=enum_name,
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
|
if not result.get("successful"):
|
||||||
|
message_str = result.get("error", {})
|
||||||
|
return {"error": message_str}
|
||||||
|
|
||||||
|
result_data = result.get("data", [])
|
||||||
|
if (
|
||||||
|
len(result_data) != 1
|
||||||
|
and not self._actions_data.get(action_key, {}).get("result_field")
|
||||||
|
and self._actions_data.get(action_key, {}).get("get_result_field")
|
||||||
|
):
|
||||||
|
msg = f"Expected a dict with a single key, got {len(result_data)} keys: {result_data.keys()}"
|
||||||
|
raise ValueError(msg)
|
||||||
|
if action_key == "GOOGLECALENDAR_GET_CURRENT_DATE_TIME":
|
||||||
|
return result_data
|
||||||
|
return result_data[next(iter(result_data))]
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error executing action: {e}")
|
||||||
|
display_name = self.action[0]["name"] if isinstance(self.action, list) and self.action else str(self.action)
|
||||||
|
msg = f"Failed to execute {display_name}: {e!s}"
|
||||||
|
raise ValueError(msg) from e
|
||||||
|
|
||||||
|
def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:
|
||||||
|
return super().update_build_config(build_config, field_value, field_name)
|
||||||
|
|
@ -0,0 +1,182 @@
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from composio import Action
|
||||||
|
from langflow.components.composio.googlecalendar_composio import ComposioGoogleCalendarAPIComponent
|
||||||
|
from langflow.schema.dataframe import DataFrame
|
||||||
|
|
||||||
|
from tests.base import DID_NOT_EXIST, ComponentTestBaseWithoutClient
|
||||||
|
|
||||||
|
from .test_base import MockComposioToolSet
|
||||||
|
|
||||||
|
|
||||||
|
class MockAction:
|
||||||
|
GOOGLECALENDAR_CREATE_EVENT = "GOOGLECALENDAR_CREATE_EVENT"
|
||||||
|
GOOGLECALENDAR_LIST_CALENDARS = "GOOGLECALENDAR_LIST_CALENDARS"
|
||||||
|
|
||||||
|
|
||||||
|
class TestGoogleCalendarComponent(ComponentTestBaseWithoutClient):
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def mock_composio_toolset(self):
|
||||||
|
with patch("langflow.base.composio.composio_base.ComposioToolSet", MockComposioToolSet):
|
||||||
|
yield
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def component_class(self):
|
||||||
|
return ComposioGoogleCalendarAPIComponent
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def default_kwargs(self):
|
||||||
|
return {
|
||||||
|
"api_key": "",
|
||||||
|
"entity_id": "default",
|
||||||
|
"action": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def file_names_mapping(self):
|
||||||
|
return [
|
||||||
|
{"version": "1.0.17", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||||
|
{"version": "1.0.18", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||||
|
{"version": "1.0.19", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||||
|
{"version": "1.1.0", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||||
|
{"version": "1.1.1", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||||
|
]
|
||||||
|
|
||||||
|
def test_init(self, component_class, default_kwargs):
|
||||||
|
component = component_class(**default_kwargs)
|
||||||
|
assert component.display_name == "Google Calendar"
|
||||||
|
assert component.app_name == "googlecalendar"
|
||||||
|
assert "GOOGLECALENDAR_CREATE_EVENT" in component._actions_data
|
||||||
|
assert "GOOGLECALENDAR_LIST_CALENDARS" in component._actions_data
|
||||||
|
|
||||||
|
def test_execute_action_create_event(self, component_class, default_kwargs, monkeypatch):
|
||||||
|
monkeypatch.setattr(Action, "GOOGLECALENDAR_CREATE_EVENT", MockAction.GOOGLECALENDAR_CREATE_EVENT)
|
||||||
|
|
||||||
|
component = component_class(**default_kwargs)
|
||||||
|
component.api_key = "test_key"
|
||||||
|
component.action = [{"name": "Create Event"}]
|
||||||
|
component.GOOGLECALENDAR_CREATE_EVENT_attendees = "test@example.com"
|
||||||
|
component.GOOGLECALENDAR_CREATE_EVENT_start_datetime = "2025-01-16T15:00:00"
|
||||||
|
component.GOOGLECALENDAR_CREATE_EVENT_summary = "test title"
|
||||||
|
|
||||||
|
component._actions_data = {
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT": {
|
||||||
|
"display_name": "Create Event",
|
||||||
|
"action_fields": [
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_description",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_eventType",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_create_meeting_room",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_guestsCanSeeOtherGuests",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_guestsCanInviteOthers",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_location",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_summary",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_transparency",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_visibility",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_timezone",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_recurrence",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_guests_can_modify",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_attendees",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_send_updates",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_start_datetime",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_event_duration_hour",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_event_duration_minutes",
|
||||||
|
"GOOGLECALENDAR_CREATE_EVENT_calendar_id",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = component.execute_action()
|
||||||
|
assert result == "mocked response"
|
||||||
|
|
||||||
|
def test_execute_action_list_calendars(self, component_class, default_kwargs, monkeypatch):
|
||||||
|
monkeypatch.setattr(Action, "GOOGLECALENDAR_LIST_CALENDARS", MockAction.GOOGLECALENDAR_LIST_CALENDARS)
|
||||||
|
|
||||||
|
component = component_class(**default_kwargs)
|
||||||
|
component.api_key = "test_key"
|
||||||
|
component.action = [{"name": "List Google Calendars"}]
|
||||||
|
component.GOOGLECALENDAR_LIST_CALENDARS_max_results = 1
|
||||||
|
|
||||||
|
component._actions_data = {
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS": {
|
||||||
|
"display_name": "List Google Calendars",
|
||||||
|
"action_fields": [
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_max_results",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_min_access_role",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_page_token",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_show_deleted",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_show_hidden",
|
||||||
|
"GOOGLECALENDAR_LIST_CALENDARS_sync_token",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mock_toolset = MagicMock()
|
||||||
|
mock_toolset.execute_action.return_value = {"successful": True, "data": {"messages": "mocked response"}}
|
||||||
|
|
||||||
|
with patch.object(component, "_build_wrapper", return_value=mock_toolset):
|
||||||
|
result = component.execute_action()
|
||||||
|
assert result == "mocked response"
|
||||||
|
|
||||||
|
def test_execute_action_invalid_action(self, component_class, default_kwargs):
|
||||||
|
component = component_class(**default_kwargs)
|
||||||
|
component.api_key = "test_key"
|
||||||
|
component.action = [{"name": "Invalid Action"}]
|
||||||
|
|
||||||
|
with pytest.raises(ValueError, match="Invalid action: Invalid Action"):
|
||||||
|
component.execute_action()
|
||||||
|
|
||||||
|
def test_as_dataframe(self, component_class, default_kwargs, monkeypatch):
|
||||||
|
monkeypatch.setattr(Action, "GOOGLECALENDAR_LIST_CALENDARS", MockAction.GOOGLECALENDAR_LIST_CALENDARS)
|
||||||
|
|
||||||
|
component = component_class(**default_kwargs)
|
||||||
|
component.api_key = "test_key"
|
||||||
|
component.action = [{"name": "List Google Calendars"}]
|
||||||
|
component.GOOGLECALENDAR_LIST_CALENDARS_max_results = 10
|
||||||
|
|
||||||
|
mock_emails = [
|
||||||
|
{
|
||||||
|
"kind": "test kind 1",
|
||||||
|
"etag": "1",
|
||||||
|
"id": "1",
|
||||||
|
"summary": "test summary 1",
|
||||||
|
"description": "test description 1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "test kind 2",
|
||||||
|
"etag": "2",
|
||||||
|
"id": "2",
|
||||||
|
"summary": "test summary 2",
|
||||||
|
"description": "test description 2",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
with patch.object(component, "execute_action", return_value=mock_emails):
|
||||||
|
result = component.as_dataframe()
|
||||||
|
|
||||||
|
assert isinstance(result, DataFrame)
|
||||||
|
|
||||||
|
assert not result.empty
|
||||||
|
|
||||||
|
data_str = str(result)
|
||||||
|
assert "test summary 2" in data_str
|
||||||
|
|
||||||
|
def test_update_build_config(self, component_class, default_kwargs):
|
||||||
|
component = component_class(**default_kwargs)
|
||||||
|
build_config = {
|
||||||
|
"auth_link": {"value": "", "auth_tooltip": ""},
|
||||||
|
"action": {
|
||||||
|
"options": [],
|
||||||
|
"helper_text": "",
|
||||||
|
"helper_text_metadata": {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
result = component.update_build_config(build_config, "", "api_key")
|
||||||
|
assert result["auth_link"]["value"] == ""
|
||||||
|
assert "Please provide a valid Composio API Key" in result["auth_link"]["auth_tooltip"]
|
||||||
|
assert result["action"]["options"] == []
|
||||||
|
|
||||||
|
component.api_key = "test_key"
|
||||||
|
result = component.update_build_config(build_config, "test_key", "api_key")
|
||||||
|
assert len(result["action"]["options"]) > 0
|
||||||
|
|
@ -38,6 +38,7 @@ import { GleanIcon } from "@/icons/Glean";
|
||||||
import { GlobeOkIcon } from "@/icons/globe-ok";
|
import { GlobeOkIcon } from "@/icons/globe-ok";
|
||||||
import { GmailIcon } from "@/icons/gmail";
|
import { GmailIcon } from "@/icons/gmail";
|
||||||
import { GoogleIcon } from "@/icons/Google";
|
import { GoogleIcon } from "@/icons/Google";
|
||||||
|
import { GooglecalendarIcon } from "@/icons/googlecalendar";
|
||||||
import { GoogleDriveIcon } from "@/icons/GoogleDrive";
|
import { GoogleDriveIcon } from "@/icons/GoogleDrive";
|
||||||
import { GoogleGenerativeAIIcon } from "@/icons/GoogleGenerativeAI";
|
import { GoogleGenerativeAIIcon } from "@/icons/GoogleGenerativeAI";
|
||||||
import {
|
import {
|
||||||
|
|
@ -156,6 +157,7 @@ export const eagerIconsMapping = {
|
||||||
GoogleDrive: GoogleDriveIcon,
|
GoogleDrive: GoogleDriveIcon,
|
||||||
GoogleGenerativeAI: GoogleGenerativeAIIcon,
|
GoogleGenerativeAI: GoogleGenerativeAIIcon,
|
||||||
Gmail: GmailIcon,
|
Gmail: GmailIcon,
|
||||||
|
Googlecalendar: GooglecalendarIcon,
|
||||||
GradientInfinity: GradientInfinity,
|
GradientInfinity: GradientInfinity,
|
||||||
GradientSave: GradientSave,
|
GradientSave: GradientSave,
|
||||||
GradientUngroup: GradientUngroup,
|
GradientUngroup: GradientUngroup,
|
||||||
|
|
|
||||||
28
src/frontend/src/icons/googlecalendar/googlecalendar.jsx
Normal file
28
src/frontend/src/icons/googlecalendar/googlecalendar.jsx
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
const Icon = (props) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 48 48"
|
||||||
|
width="23px"
|
||||||
|
height="23px"
|
||||||
|
>
|
||||||
|
<rect width="22" height="22" x="13" y="13" fill="#fff" />
|
||||||
|
<polygon
|
||||||
|
fill="#1e88e5"
|
||||||
|
points="25.68,20.92 26.688,22.36 28.272,21.208 28.272,29.56 30,29.56 30,18.616 28.56,18.616"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#1e88e5"
|
||||||
|
d="M22.943,23.745c0.625-0.574,1.013-1.37,1.013-2.249c0-1.747-1.533-3.168-3.417-3.168 c-1.602,0-2.972,1.009-3.33,2.453l1.657,0.421c0.165-0.664,0.868-1.146,1.673-1.146c0.942,0,1.709,0.646,1.709,1.44 c0,0.794-0.767,1.44-1.709,1.44h-0.997v1.728h0.997c1.081,0,1.993,0.751,1.993,1.64c0,0.904-0.866,1.64-1.931,1.64 c-0.962,0-1.784-0.61-1.914-1.418L17,26.802c0.262,1.636,1.81,2.87,3.6,2.87c2.007,0,3.64-1.511,3.64-3.368 C24.24,25.281,23.736,24.363,22.943,23.745z"
|
||||||
|
/>
|
||||||
|
<polygon fill="#fbc02d" points="34,42 14,42 13,38 14,34 34,34 35,38" />
|
||||||
|
<polygon fill="#4caf50" points="38,35 42,34 42,14 38,13 34,14 34,34" />
|
||||||
|
<path
|
||||||
|
fill="#1e88e5"
|
||||||
|
d="M34,14l1-4l-1-4H9C7.343,6,6,7.343,6,9v25l4,1l4-1V14H34z"
|
||||||
|
/>
|
||||||
|
<polygon fill="#e53935" points="34,34 34,42 42,34" />
|
||||||
|
<path fill="#1565c0" d="M39,6h-5v8h8V9C42,7.343,40.657,6,39,6z" />
|
||||||
|
<path fill="#1565c0" d="M9,42h5v-8H6v5C6,40.657,7.343,42,9,42z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
export default Icon;
|
||||||
1
src/frontend/src/icons/googlecalendar/googlecalendar.svg
Normal file
1
src/frontend/src/icons/googlecalendar/googlecalendar.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="23px" height="23px"><rect width="22" height="22" x="13" y="13" fill="#fff"/><polygon fill="#1e88e5" points="25.68,20.92 26.688,22.36 28.272,21.208 28.272,29.56 30,29.56 30,18.616 28.56,18.616"/><path fill="#1e88e5" d="M22.943,23.745c0.625-0.574,1.013-1.37,1.013-2.249c0-1.747-1.533-3.168-3.417-3.168 c-1.602,0-2.972,1.009-3.33,2.453l1.657,0.421c0.165-0.664,0.868-1.146,1.673-1.146c0.942,0,1.709,0.646,1.709,1.44 c0,0.794-0.767,1.44-1.709,1.44h-0.997v1.728h0.997c1.081,0,1.993,0.751,1.993,1.64c0,0.904-0.866,1.64-1.931,1.64 c-0.962,0-1.784-0.61-1.914-1.418L17,26.802c0.262,1.636,1.81,2.87,3.6,2.87c2.007,0,3.64-1.511,3.64-3.368 C24.24,25.281,23.736,24.363,22.943,23.745z"/><polygon fill="#fbc02d" points="34,42 14,42 13,38 14,34 34,34 35,38"/><polygon fill="#4caf50" points="38,35 42,34 42,14 38,13 34,14 34,34"/><path fill="#1e88e5" d="M34,14l1-4l-1-4H9C7.343,6,6,7.343,6,9v25l4,1l4-1V14H34z"/><polygon fill="#e53935" points="34,34 34,42 42,34"/><path fill="#1565c0" d="M39,6h-5v8h8V9C42,7.343,40.657,6,39,6z"/><path fill="#1565c0" d="M9,42h5v-8H6v5C6,40.657,7.343,42,9,42z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
9
src/frontend/src/icons/googlecalendar/index.tsx
Normal file
9
src/frontend/src/icons/googlecalendar/index.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import React, { forwardRef } from "react";
|
||||||
|
import GooglecalendarIconSVG from "./googlecalendar";
|
||||||
|
|
||||||
|
export const GooglecalendarIcon = forwardRef<
|
||||||
|
SVGSVGElement,
|
||||||
|
React.PropsWithChildren<{}>
|
||||||
|
>((props, ref) => {
|
||||||
|
return <GooglecalendarIconSVG ref={ref} {...props} />;
|
||||||
|
});
|
||||||
|
|
@ -97,6 +97,10 @@ export const lazyIconsMapping = {
|
||||||
})),
|
})),
|
||||||
Gmail: () =>
|
Gmail: () =>
|
||||||
import("@/icons/gmail").then((mod) => ({ default: mod.GmailIcon })),
|
import("@/icons/gmail").then((mod) => ({ default: mod.GmailIcon })),
|
||||||
|
Googlecalendar: () =>
|
||||||
|
import("@/icons/googlecalendar").then((mod) => ({
|
||||||
|
default: mod.GooglecalendarIcon,
|
||||||
|
})),
|
||||||
GradientInfinity: () =>
|
GradientInfinity: () =>
|
||||||
import("@/icons/GradientSparkles").then((mod) => ({
|
import("@/icons/GradientSparkles").then((mod) => ({
|
||||||
default: mod.GradientInfinity,
|
default: mod.GradientInfinity,
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,11 @@ export const SIDEBAR_CATEGORIES = [
|
||||||
export const SIDEBAR_BUNDLES = [
|
export const SIDEBAR_BUNDLES = [
|
||||||
{ display_name: "Amazon", name: "amazon", icon: "Amazon" },
|
{ display_name: "Amazon", name: "amazon", icon: "Amazon" },
|
||||||
{ display_name: "Gmail", name: "gmail", icon: "Gmail" },
|
{ display_name: "Gmail", name: "gmail", icon: "Gmail" },
|
||||||
|
{
|
||||||
|
display_name: "Googlecalendar",
|
||||||
|
name: "googlecalendar",
|
||||||
|
icon: "Googlecalendar",
|
||||||
|
},
|
||||||
// Add apify
|
// Add apify
|
||||||
{ display_name: "Apify", name: "apify", icon: "Apify" },
|
{ display_name: "Apify", name: "apify", icon: "Apify" },
|
||||||
{ display_name: "LangChain", name: "langchain_utilities", icon: "LangChain" },
|
{ display_name: "LangChain", name: "langchain_utilities", icon: "LangChain" },
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue