-
Notifications
You must be signed in to change notification settings - Fork 488
feat: Add Zendesk connector integration #243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This commit introduces the Zendesk connector, allowing users to integrate and search their Zendesk tickets. Key changes include: - Backend: - Added `ZendeskConnector` class for API interaction. - Updated `DocumentType` and `SearchSourceConnectorType` enums. - Integrated Zendesk indexing into `search_source_connectors_routes.py` and `connectors_indexing_tasks.py`. - Added `httpx` dependency to `pyproject.toml`. - Frontend: - Added Zendesk connector to the "Add Connector" page. - Implemented Zendesk connector configuration fields in the "Edit Connector" page. - Updated `biome.json` schema version. - Updated `ModernHeroWithGradients.tsx` to include Zendesk in the list of external sources.
@KafilatAdeleke is attempting to deploy a commit to the Rohan Verma's projects Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThis change introduces a Zendesk connector across the backend and frontend. It adds enum values, validation, and migration logic for the new connector type in the backend, implements the connector class for Zendesk API integration, and scaffolds (commented) indexing code. The frontend is updated to support creation, editing, and categorization of Zendesk connectors with appropriate forms, validation, and documentation UI. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Frontend
participant Backend
participant Zendesk API
User->>Frontend: Fill Zendesk connector form and submit
Frontend->>Backend: POST /connectors (Zendesk config)
Backend->>Backend: Validate config for ZENDESK_CONNECTOR
Backend->>Backend: Store connector in DB
Backend-->>Frontend: Success/Failure response
Frontend-->>User: Show confirmation or error
User->>Frontend: Initiate ticket indexing (future)
Frontend->>Backend: Request to index Zendesk tickets
Backend->>Zendesk API: Fetch tickets (paginated)
Zendesk API-->>Backend: Return ticket data
Backend->>Backend: Store tickets, update last indexed
Backend-->>Frontend: Indexing status
Frontend-->>User: Show indexing progress/result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~15–20 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
✨ No issues found! Your code is sparkling clean! ✨ Need help? Join our Discord for support! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (6)
surfsense_web/components/ModernHeroWithGradients.tsx (1)
52-55
: Add “Zendesk” to the marketing copy to advertise the new connectorThe PR’s main feature is Zendesk integration, but the hero text still omits Zendesk in the external-sources list. Updating this copy keeps the UI consistent with the newly delivered capability.
- external sources such as Search Engines, Slack, Linear, Jira, Confluence, Notion, - YouTube, GitHub, Discord and more. + external sources such as Search Engines, Slack, Linear, Jira, Confluence, Notion, + Zendesk, YouTube, GitHub, Discord and more.docker-compose.override.yml (2)
35-35
: Trim trailing whitespace.Line 35 contains trailing spaces, triggering the YAML-lint warning.
This is purely cosmetic but easy to fix.- +
31-33
: Confirm need for GPU-related env vars now that the GPUdeploy
block is gone.With the entire
deploy.resources.reservations.devices
section removed, the backend container is no longer scheduled with GPU-specific constraints. Keeping- NVIDIA_VISIBLE_DEVICES=all - NVIDIA_DRIVER_CAPABILITIES=compute,utilitymay confuse future readers and can cause Docker to complain on hosts without the NVIDIA runtime. Consider deleting these lines unless the container still performs CUDA work.
- - NVIDIA_VISIBLE_DEVICES=all - - NVIDIA_DRIVER_CAPABILITIES=compute,utilitysurfsense_web/components/editConnector/types.ts (1)
42-44
: Consider adding validation for Zendesk configuration fields.The Zendesk configuration fields follow the correct naming pattern. Consider adding validation rules for better user experience:
ZENDESK_SUBDOMAIN: z.string().optional(), - ZENDESK_EMAIL: z.string().optional(), - ZENDESK_API_TOKEN: z.string().optional(), + ZENDESK_EMAIL: z.string().email("Please enter a valid email address").optional(), + ZENDESK_API_TOKEN: z.string().min(1, "API token cannot be empty").optional(),surfsense_web/app/dashboard/[search_space_id]/connectors/add/page.tsx (1)
139-151
: Consider using a different icon to distinguish from Jira.The Zendesk connector implementation looks good and follows the established pattern. However, both Zendesk and Jira use the same
IconTicket
component, which might cause visual confusion for users.Consider using a different icon for Zendesk to improve visual distinction:
- icon: <IconTicket className="h-6 w-6" />, + icon: <IconHeadset className="h-6 w-6" />,Don't forget to add the import:
import { IconBook, IconBrandDiscord, IconBrandGithub, IconBrandNotion, IconBrandSlack, IconBrandWindows, IconBrandZoom, IconChevronDown, IconChevronRight, + IconHeadset, IconLayoutKanban, IconLinkPlus, IconMail, IconTicket, IconWorldWww, } from "@tabler/icons-react";
surfsense_backend/alembic/versions/15_add_zendesk_connector_enums.py (1)
56-61
: Consider enhancing downgrade documentation.While PostgreSQL doesn't support enum value removal, the downgrade function could provide more detailed guidance for manual cleanup if needed.
def downgrade() -> None: """ - Downgrade logic not implemented since PostgreSQL - does not support removing enum values. + Downgrade logic not implemented since PostgreSQL does not support removing enum values. + + If manual cleanup is required: + 1. Ensure no database records reference 'ZENDESK_CONNECTOR' enum values + 2. Manually recreate enum types without the ZENDESK_CONNECTOR value + 3. Update all dependent tables to use the new enum types """ pass
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
biome.json
(1 hunks)docker-compose.override.yml
(1 hunks)surfsense_backend/alembic/versions/15_add_zendesk_connector_enums.py
(1 hunks)surfsense_backend/app/connectors/zendesk_connector.py
(1 hunks)surfsense_backend/app/db.py
(2 hunks)surfsense_backend/app/routes/search_source_connectors_routes.py
(3 hunks)surfsense_backend/app/schemas/search_source_connector.py
(1 hunks)surfsense_backend/app/tasks/connectors_indexing_tasks.py
(2 hunks)surfsense_backend/pyproject.toml
(1 hunks)surfsense_browser_extension/biome.json
(1 hunks)surfsense_web/app/dashboard/[search_space_id]/connectors/[connector_id]/edit/page.tsx
(1 hunks)surfsense_web/app/dashboard/[search_space_id]/connectors/add/page.tsx
(1 hunks)surfsense_web/app/dashboard/[search_space_id]/connectors/add/zendesk-connector/page.tsx
(1 hunks)surfsense_web/biome.json
(1 hunks)surfsense_web/components/ModernHeroWithGradients.tsx
(1 hunks)surfsense_web/components/editConnector/types.ts
(1 hunks)surfsense_web/hooks/useConnectorEditPage.ts
(4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
surfsense_backend/app/connectors/zendesk_connector.py (1)
surfsense_web/lib/api.ts (1)
get
(82-94)
surfsense_backend/app/schemas/search_source_connector.py (1)
surfsense_backend/app/db.py (1)
SearchSourceConnectorType
(50-61)
surfsense_web/app/dashboard/[search_space_id]/connectors/[connector_id]/edit/page.tsx (1)
surfsense_web/components/editConnector/EditSimpleTokenForm.tsx (1)
EditSimpleTokenForm
(24-49)
🪛 YAMLlint (1.37.1)
docker-compose.override.yml
[error] 35-35: trailing spaces
(trailing-spaces)
🔇 Additional comments (21)
biome.json (1)
2-2
: Schema version bump looks goodUpdating to 2.1.3 keeps the config current with Biome’s latest tooling. No other config changes are introduced, so no action needed.
surfsense_web/biome.json (1)
2-3
:root: false
+ schema bump are sensibleSetting
root
to false allows the project-level configuration to take precedence, and the schema bump keeps the file in sync with the root config. Looks consistent with the other directories.surfsense_browser_extension/biome.json (1)
2-3
: Consistent Biome updateMatches the pattern in
surfsense_web
; no issues spotted.surfsense_backend/pyproject.toml (1)
38-38
: httpx dependency addition verified
- PyPI releases confirm
0.27.0
exists (with patches up to0.27.2
); the latest httpx is0.28.1
, so>=0.27.0
will pull in current stable releases.- GitHub security advisories report a single critical issue affecting only
<0.23.0
, which is patched in0.23.0
—versions>=0.27.0
are not impacted.✅ No known vulnerabilities for httpx >= 0.27.0; this dependency addition can be approved.
surfsense_backend/app/db.py (3)
47-47
: LGTM! Enum addition follows existing pattern.The ZENDESK_CONNECTOR addition to DocumentType enum is consistent with other connector types.
51-51
: Good cleanup of the comment typo.Fixed the capitalization in "RETURNed" - nice attention to detail.
61-61
: LGTM! SearchSourceConnectorType enum properly extended.The ZENDESK_CONNECTOR addition maintains consistency with existing connector types and aligns with the database migration requirements.
surfsense_backend/app/schemas/search_source_connector.py (1)
170-189
: LGTM! Zendesk validation follows established patterns.The validation logic for the Zendesk connector is well-implemented:
- Properly validates all three required configuration fields
- Follows the same pattern as other multi-field connectors (Jira, Confluence)
- Includes appropriate empty value checks for security
- Error messages are descriptive and consistent
The implementation correctly ensures that sensitive credentials cannot be empty and that only expected configuration keys are present.
surfsense_web/app/dashboard/[search_space_id]/connectors/[connector_id]/edit/page.tsx (1)
253-278
: LGTM! Consistent implementation following established patterns.The Zendesk connector configuration form follows the same pattern as other multi-field connectors (Jira, Confluence) with appropriate field names, descriptions, and validation. The implementation is clean and consistent with the existing codebase.
surfsense_backend/alembic/versions/15_add_zendesk_connector_enums.py (1)
18-53
: LGTM! Safe migration implementation with proper conditional logic.The migration properly uses conditional PL/pgSQL blocks to safely add enum values without causing errors if they already exist. The approach handles both required enum types correctly.
surfsense_web/hooks/useConnectorEditPage.ts (4)
55-57
: LGTM! Consistent form field initialization.The Zendesk form fields are properly initialized in the default values, following the same pattern as other connectors.
84-86
: LGTM! Proper form reset logic.The form reset logic correctly populates Zendesk fields from the connector configuration, maintaining consistency with the existing pattern.
312-333
: LGTM! Consistent validation and save logic.The Zendesk connector case follows the exact same pattern as Jira and Confluence connectors with proper validation, error handling, and configuration object creation.
396-399
: LGTM! Proper form state reset after successful save.The form values are correctly reset to the saved configuration values after a successful update, maintaining consistency with other connector types.
surfsense_web/app/dashboard/[search_space_id]/connectors/add/zendesk-connector/page.tsx (3)
53-95
: LGTM! Well-structured component with proper form handling.The component follows React best practices with proper form validation, error handling, loading states, and user feedback. The integration with the
createConnector
hook is implemented correctly.
113-235
: LGTM! Excellent user experience with clear form layout.The tabbed interface provides a clean separation between the connection form and documentation. Form fields have appropriate labels, descriptions, and placeholders. The alert about API token requirements is helpful for users.
238-281
: LGTM! Helpful documentation with clear setup instructions.The documentation tab provides clear, step-by-step instructions for generating a Zendesk API token. The accordion layout keeps the information organized and accessible.
surfsense_backend/app/routes/search_source_connectors_routes.py (3)
46-46
: LGTM!The import is correctly placed and follows the established pattern with other connector indexing functions.
492-505
: LGTM!The Zendesk connector handling follows the established pattern perfectly, with proper logging, background task scheduling, and consistent parameter passing.
981-1035
: Approved: Zendesk indexing helpers and signature verifiedThe
index_zendesk_tickets
function is present insurfsense_backend/app/tasks/connectors_indexing_tasks.py
with the following signature, which matches its invocation in your new helpers:
session: AsyncSession
connector_id: int
search_space_id: int
user_id: str
start_date: str | None = None
end_date: str | None = None
update_last_indexed: bool = True
No further changes are required—your wrapper and main indexing functions follow the established pattern, with proper session handling, logging, error management, and timestamp updates.
surfsense_backend/app/tasks/connectors_indexing_tasks.py (1)
18-18
: LGTM!The import is correctly placed with other connector imports in alphabetical order.
class ZendeskConnector: | ||
def __init__(self, subdomain: str, email: str, api_token: str): | ||
self.base_url = f"https://{subdomain}.zendesk.com/api/v2" | ||
self.auth = (f"{email}/token", api_token) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add parameter validation for constructor arguments.
The constructor should validate that the required parameters are not empty and that the subdomain follows expected format patterns to prevent runtime errors.
class ZendeskConnector:
def __init__(self, subdomain: str, email: str, api_token: str):
+ if not subdomain or not subdomain.strip():
+ raise ValueError("Subdomain cannot be empty")
+ if not email or not email.strip():
+ raise ValueError("Email cannot be empty")
+ if not api_token or not api_token.strip():
+ raise ValueError("API token cannot be empty")
+
self.base_url = f"https://{subdomain}.zendesk.com/api/v2"
self.auth = (f"{email}/token", api_token)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
class ZendeskConnector: | |
def __init__(self, subdomain: str, email: str, api_token: str): | |
self.base_url = f"https://{subdomain}.zendesk.com/api/v2" | |
self.auth = (f"{email}/token", api_token) | |
class ZendeskConnector: | |
def __init__(self, subdomain: str, email: str, api_token: str): | |
if not subdomain or not subdomain.strip(): | |
raise ValueError("Subdomain cannot be empty") | |
if not email or not email.strip(): | |
raise ValueError("Email cannot be empty") | |
if not api_token or not api_token.strip(): | |
raise ValueError("API token cannot be empty") | |
self.base_url = f"https://{subdomain}.zendesk.com/api/v2" | |
self.auth = (f"{email}/token", api_token) |
🤖 Prompt for AI Agents
In surfsense_backend/app/connectors/zendesk_connector.py around lines 4 to 8,
the constructor lacks validation for its parameters. Add checks to ensure
subdomain, email, and api_token are not empty or None. Additionally, validate
that the subdomain matches expected format patterns (e.g., allowed characters
and length). Raise appropriate exceptions if validations fail to prevent runtime
errors later.
async def index_zendesk_tickets( | ||
session: AsyncSession, | ||
connector_id: int, | ||
search_space_id: int, | ||
user_id: str, | ||
start_date: str | None = None, | ||
end_date: str | None = None, | ||
update_last_indexed: bool = True, | ||
) -> tuple[int, str | None]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider using date parameters for filtering tickets.
The start_date
and end_date
parameters are accepted but never used in the function implementation. Unlike other indexing functions in this file, the Zendesk implementation doesn't filter tickets by date range. This could lead to performance issues with large ticket volumes and inconsistent behavior compared to other connectors.
Consider implementing date filtering for Zendesk tickets:
async def index_zendesk_tickets(
session: AsyncSession,
connector_id: int,
search_space_id: int,
user_id: str,
start_date: str | None = None,
end_date: str | None = None,
update_last_indexed: bool = True,
) -> tuple[int, str | None]:
"""
Index Zendesk tickets.
Args:
session: Database session
connector_id: ID of the Zendesk connector
search_space_id: ID of the search space to store documents in
+ user_id: User ID
+ start_date: Start date for indexing (YYYY-MM-DD format)
+ end_date: End date for indexing (YYYY-MM-DD format)
update_last_indexed: Whether to update the last_indexed_at timestamp (default: True)
Returns:
Tuple containing (number of documents indexed, error message or None)
"""
Additionally, implement date range calculation and pass it to the get_tickets()
method similar to other connectors.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In surfsense_backend/app/tasks/connectors_indexing_tasks.py around lines 2704 to
2712, the start_date and end_date parameters are defined but not used to filter
Zendesk tickets, which can cause performance issues and inconsistency. Modify
the function to calculate the date range based on these parameters and pass this
date range to the get_tickets() method to filter tickets accordingly, following
the pattern used in other connector indexing functions.
if not all([ticket_id, ticket_subject, ticket_description]): | ||
documents_skipped += 1 | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add logging for skipped tickets.
When tickets are skipped due to missing required fields, there's no logging to track which tickets were skipped or why. This makes debugging and auditing difficult.
if not all([ticket_id, ticket_subject, ticket_description]):
+ logger.warning(
+ f"Skipping ticket with missing data - ID: {ticket_id or 'None'}, "
+ f"Subject: {ticket_subject or 'None'}, "
+ f"Description: {'Present' if ticket_description else 'None'}"
+ )
documents_skipped += 1
continue
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if not all([ticket_id, ticket_subject, ticket_description]): | |
documents_skipped += 1 | |
continue | |
if not all([ticket_id, ticket_subject, ticket_description]): | |
logger.warning( | |
f"Skipping ticket with missing data - ID: {ticket_id or 'None'}, " | |
f"Subject: {ticket_subject or 'None'}, " | |
f"Description: {'Present' if ticket_description else 'None'}" | |
) | |
documents_skipped += 1 | |
continue |
🤖 Prompt for AI Agents
In surfsense_backend/app/tasks/connectors_indexing_tasks.py around lines 2827 to
2829, add logging to record when tickets are skipped due to missing required
fields. Modify the code inside the if condition to log which ticket is being
skipped and specify which required fields are missing before incrementing
documents_skipped and continuing. Use an appropriate logger to output this
information for better debugging and auditing.
user_llm = await get_user_long_context_llm(session, user_id) | ||
if not user_llm: | ||
documents_skipped += 1 | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add logging when LLM is not configured.
Similar to the missing fields issue, when tickets are skipped due to missing LLM configuration, there's no logging to indicate this problem.
user_llm = await get_user_long_context_llm(session, user_id)
if not user_llm:
+ logger.error(f"No long context LLM configured for user {user_id}")
documents_skipped += 1
continue
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
user_llm = await get_user_long_context_llm(session, user_id) | |
if not user_llm: | |
documents_skipped += 1 | |
continue | |
user_llm = await get_user_long_context_llm(session, user_id) | |
if not user_llm: | |
logger.error(f"No long context LLM configured for user {user_id}") | |
documents_skipped += 1 | |
continue |
🤖 Prompt for AI Agents
In surfsense_backend/app/tasks/connectors_indexing_tasks.py around lines 2846 to
2849, add a logging statement when user_llm is not configured and tickets are
skipped. This log should clearly indicate that the skip is due to missing LLM
configuration, helping to track and debug such cases. Use the existing logger to
output a warning or info message before continuing the loop.
const zendeskConnectorFormSchema = z.object({ | ||
name: z.string().min(3, { | ||
message: "Connector name must be at least 3 characters.", | ||
}), | ||
subdomain: z.string().min(3, { message: "Subdomain must be at least 3 characters." }), | ||
email: z.string().email({ message: "Invalid email address." }), | ||
api_token: z.string().min(20, { message: "API token appears to be too short." }), | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify API token length validation.
The schema requires API tokens to be at least 20 characters, but Zendesk API tokens may have different length requirements. Consider verifying the actual token format and length requirements.
🌐 Web query:
What is the typical length and format of Zendesk API tokens?
💡 Result:
A typical Zendesk API token is a randomly generated string used for authenticating API requests, with the following format and length: it consists of 40 alphanumeric characters (letters and numbers) without special characters or separators[4][6][7][9]. For example:
6wiIBWbGkBMo1mRDMuVwkw1EPsNkeUj95PIz2akv
This token is used in basic authentication, concatenated with an email address and the literal word “token” as shown:
{email_address}/token:{api_token}
When encoding credentials for the Authorization header, the string [email protected]/token:6wiIBWbGkBMo1mRDMuVwkw1EPsNkeUj95PIz2akv
(where the part after the colon is the API token) is base64 encoded[4][7].
Key points:
- Length: Always exactly 40 characters.
- Format: Alphanumeric, case-sensitive.
- No separators or special formatting within the token itself.
Note: Zendesk also supports other token types (OAuth, JWT), but the classic API token for basic authentication described above always follows this 40-character format[4][9].
Citations:
- 1: https://developer.zendesk.com/documentation/help_center/help-center-api/secured-requests/
- 2: https://developer.zendesk.com/documentation/api-basics/authentication/creating-and-using-oauth-tokens-with-the-api/
- 3: https://developer.zendesk.com/api-reference/introduction/data-types/
- 4: https://developer.zendesk.com/api-reference/introduction/security-and-auth/
- 5: https://developer.zendesk.com/api-reference/help_center/help-center-api/help_center_jwts/
- 6: https://developer.zendesk.com/api-reference/ticketing/ticket-management/incremental_exports/
- 7: https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/
- 8: https://developer.zendesk.com/documentation/conversations/getting-started/api-authentication/
- 9: https://handbook.gitlab.com/handbook/security/customer-support-operations/workflows/zendesk/api/
- 10: https://developer.zendesk.com/api-reference/ticketing/oauth/grant_type_tokens/
Enforce exact 40-character alphanumeric API token
The official Zendesk API token is always exactly 40 alphanumeric characters (case-sensitive, no separators). Update the Zod schema accordingly:
• File: surfsense_web/app/dashboard/[search_space_id]/connectors/add/zendesk-connector/page.tsx
• Around lines 41–48 (the api_token
field)
Suggested diff:
- api_token: z.string().min(20, { message: "API token appears to be too short." }),
+ api_token: z
+ .string()
+ .length(40, { message: "API token must be exactly 40 characters." })
+ .regex(/^[A-Za-z0-9]+$/, { message: "API token must be alphanumeric." }),
This ensures strict validation against the 40-character, alphanumeric format mandated by Zendesk.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const zendeskConnectorFormSchema = z.object({ | |
name: z.string().min(3, { | |
message: "Connector name must be at least 3 characters.", | |
}), | |
subdomain: z.string().min(3, { message: "Subdomain must be at least 3 characters." }), | |
email: z.string().email({ message: "Invalid email address." }), | |
api_token: z.string().min(20, { message: "API token appears to be too short." }), | |
}); | |
const zendeskConnectorFormSchema = z.object({ | |
name: z.string().min(3, { | |
message: "Connector name must be at least 3 characters.", | |
}), | |
subdomain: z.string().min(3, { message: "Subdomain must be at least 3 characters." }), | |
email: z.string().email({ message: "Invalid email address." }), | |
api_token: z | |
.string() | |
.length(40, { message: "API token must be exactly 40 characters." }) | |
.regex(/^[A-Za-z0-9]+$/, { message: "API token must be alphanumeric." }), | |
}); |
🤖 Prompt for AI Agents
In
surfsense_web/app/dashboard/[search_space_id]/connectors/add/zendesk-connector/page.tsx
around lines 41 to 48, the api_token field currently validates only a minimum
length of 20 characters. Update this validation to enforce that the api_token is
exactly 40 characters long and contains only alphanumeric characters (both
uppercase and lowercase). Use a regex pattern in the Zod schema to strictly
match 40 alphanumeric characters without any separators.
@KafilatAdeleke Hey, I just merged the other PR. Could you resolve the merge conflicts and let me know once it's done? I’ll test and merge it after that. Thanks for all your hard work so far! 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
surfsense_backend/app/connectors/zendesk_connector.py (1)
7-11
: Enhance parameter validation beyond basic truthy checks.While the basic validation addresses the previous concern about empty parameters, consider adding format validation for better robustness:
def __init__(self, subdomain: str, email: str, api_token: str): if not subdomain or not email or not api_token: raise ValueError("Subdomain, email, and API token cannot be empty.") + if not subdomain.strip() or ' ' in subdomain: + raise ValueError("Subdomain must be a valid string without spaces") + if '@' not in email or '.' not in email.split('@')[-1]: + raise ValueError("Email must be a valid email address") + if len(api_token.strip()) < 10: + raise ValueError("API token appears to be too short") self.base_url = f"https://{subdomain}.zendesk.com/api/v2" self.auth = (f"{email}/token", api_token)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
surfsense_backend/app/connectors/zendesk_connector.py
(1 hunks)surfsense_web/components/editConnector/types.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- surfsense_web/components/editConnector/types.ts
🔇 Additional comments (1)
surfsense_backend/app/connectors/zendesk_connector.py (1)
1-3
: LGTM!The imports are clean and appropriately used throughout the implementation.
This commit introduces the Zendesk connector, allowing users to integrate and search their Zendesk tickets.
Key changes include:
ZendeskConnector
class for API interaction.DocumentType
andSearchSourceConnectorType
enums.search_source_connectors_routes.py
andconnectors_indexing_tasks.py
.httpx
dependency topyproject.toml
.biome.json
schema version.ModernHeroWithGradients.tsx
to include Zendesk in the list of external sources.closes #220
Description
Motivation and Context
FIX #
Changes Overview
Screenshots
API Changes
Types of changes
Testing
Checklist:
Summary by CodeRabbit
New Features
Improvements
Dependency Updates
httpx
package for backend HTTP requests.Other