-
Notifications
You must be signed in to change notification settings - Fork 4
feat(integrations): Add ClickSend integration provider #316
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?
feat(integrations): Add ClickSend integration provider #316
Conversation
WalkthroughThis change introduces a new integration for ClickSend, encompassing configuration, implementation, documentation, schema definitions, and comprehensive testing. The integration is declared in both Suggested labels
✨ Finishing Touches
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:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
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: 9
🧹 Nitpick comments (15)
integrations/clicksend/tests/clicksend-fetch-account.test.ts (1)
12-18
: Consider adding edge case testsWhile the happy path test is good, consider adding tests for error scenarios such as API failures or malformed responses to ensure robust error handling.
it('should output the action output that is expected', async () => { const input = await nangoMock.getInput(); const response = await runAction(nangoMock, input); const output = await nangoMock.getOutput(); expect(response).toEqual(output); }); +it('should handle API errors gracefully', async () => { + // Modify the mock to simulate an API error + nangoMock.proxy.mockResolvedValueOnce({ + status: 500, + data: { error: 'Internal Server Error' } + }); + + const input = await nangoMock.getInput(); + + // The action should throw an ActionError with appropriate message + await expect(runAction(nangoMock, input)).rejects.toThrow(); +});integrations/clicksend/actions/fetch-account.md (2)
22-22
: Fix markdown syntax for heading.The markdown linter flagged an issue with using emphasis instead of a heading. Replace the emphasis with a proper heading.
-_No request parameters_ +### No request parameters🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
22-22: Emphasis used instead of a heading
null(MD036, no-emphasis-as-heading)
26-26
: Fix markdown syntax for heading.The markdown linter flagged an issue with using emphasis instead of a heading. Replace the emphasis with a proper heading.
-_No request body_ +### No request body🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
26-26: Emphasis used instead of a heading
null(MD036, no-emphasis-as-heading)
integrations/clicksend/actions/fetch-account.ts (2)
5-5
: Avoid usingvoid
for an unused input parameter.
The_input?: void
signature can be confusing—consider removing the unused parameter entirely or typing it asundefined
to improve readability.-export default async function runAction(nango: NangoAction, _input?: void): Promise<Account> { +export default async function runAction(nango: NangoAction): Promise<Account> {🧰 Tools
🪛 Biome (1.9.4)
[error] 5-5: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
7-11
: Explicitly include an emptyparams
object in the proxy config.
Following the established pattern for proxy calls, addingparams: {}
signals there are no query parameters and keeps the shape consistent across integrations.const response = await nango.proxy({ endpoint: '/account', + params: {}, method: 'GET', retries: 3 });
integrations/clicksend/syncs/sms-history.md (3)
24-24
: Add missing space after punctuation.
Ensure sentences are separated properly by a space: changetime.If
totime. If
.- ... a specific point in time.If not provided... + ... a specific point in time. If not provided...🧰 Tools
🪛 LanguageTool
[style] ~24-~24: This phrase is redundant. Consider writing “point” or “time”.
Context: ...fetch records modified after a specific point in time.If not provided, all records are return...(MOMENT_IN_TIME)
26-26
: Correct pluralization.
Change “An array of string” to “An array of strings” for grammatical accuracy.- **ids:** `(optional, string[])` An array of string containing... + **ids:** `(optional, string[])` An array of strings containing...🧰 Tools
🪛 LanguageTool
[uncategorized] ~26-~26: The grammatical number of this noun doesn’t look right. Consider replacing it.
Context: ...ray of string containing a list of your records IDs. The list will be filtered to inclu...(AI_EN_LECTOR_REPLACEMENT_NOUN_NUMBER)
9-9
: Use plain text instead of emphasis for “None.”
Avoid italicizing_None_
; use unformatted text to improve clarity.- - **Scopes:** _None_ + - **Scopes:** Noneintegrations/clicksend/actions/send-sms.md (1)
2-2
: Use consistent capitalization for SMS.
Update the heading from “Send Sms” to “Send SMS” to match the acronym style used elsewhere.- # Send Sms + # Send SMSintegrations/clicksend/syncs/sms-history.ts (1)
6-6
: Consider using a more specific type for paramsWhile
Record<string, any>
works, consider using a more specific type for better type safety, such asRecord<string, string | number>
since you're only adding timestamps.-const params: Record<string, any> = {}; +const params: Record<string, string | number> = {};integrations/clicksend/tests/clicksend-send-sms.test.ts (1)
5-19
: Consider adding more test casesThe test is well-structured but only covers the happy path. Consider adding test cases for:
- Invalid input validation
- Error handling scenarios
- Edge cases (e.g., empty fields)
This would improve test coverage and ensure robustness.
demo-github-integration/syncs/github-issue-example.ts (4)
1-1
: Consider importing specific typesYour import statement is using a relative path (
'../../models'
). For better maintenance, consider using path aliases if your project supports them, or import specific types directly from their source files.
16-16
: Use TypeScript type guards for safer type checkingThe current type filtering relies on property checks without proper type narrowing.
- const issues: any[] = issueBatch.filter((issue: any) => !('pull_request' in issue)); + const issues: GitHubIssue[] = issueBatch.filter((issue: GitHubIssue): issue is GitHubIssue => + !('pull_request' in issue));
32-35
: Consider adding record count metricsThe current implementation logs the number of issues processed per repository, but doesn't track the total issues synced.
+ let totalIssueCount = 0; // Inside the repository loop if (mappedIssues.length > 0) { await nango.batchSave(mappedIssues, 'GithubIssue'); await nango.log(`Sent ${mappedIssues.length} issues from ${repo.owner.login}/${repo.name}`); + totalIssueCount += mappedIssues.length; } // At the end of the fetchData function + await nango.log(`Total GitHub issues synced: ${totalIssueCount}`);
9-14
: Consider adding rate limit protection for the GitHub APIGitHub has strict rate limits. Add retry configuration to handle potential rate limit errors.
const proxyConfig = { endpoint: `/repos/${repo.owner.login}/${repo.name}/issues`, paginate: { limit: LIMIT }, + retries: 3, + retryOn: [429, 503] };
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
dist/github-issue-example-demo-github-integration.js
is excluded by!**/dist/**
📒 Files selected for processing (25)
.nango/schema.json
(1 hunks).nango/schema.ts
(1 hunks)demo-github-integration/syncs/github-issue-example.ts
(1 hunks)flows.yaml
(1 hunks)integrations/clicksend/.nango/schema.json
(1 hunks)integrations/clicksend/.nango/schema.ts
(1 hunks)integrations/clicksend/actions/fetch-account.md
(1 hunks)integrations/clicksend/actions/fetch-account.ts
(1 hunks)integrations/clicksend/actions/send-sms.md
(1 hunks)integrations/clicksend/actions/send-sms.ts
(1 hunks)integrations/clicksend/mappers/to-account.ts
(1 hunks)integrations/clicksend/mappers/to-sms.ts
(1 hunks)integrations/clicksend/mocks/fetch-account/output.json
(1 hunks)integrations/clicksend/mocks/nango/get/proxy/account/fetch-account/abd756729884886e6a97f89f107907c4d96aa044.json
(1 hunks)integrations/clicksend/mocks/nango/post/proxy/sms/send/send-sms/ef821ad18258311a60ec6e84cd2316729825303d.json
(1 hunks)integrations/clicksend/mocks/send-sms/input.json
(1 hunks)integrations/clicksend/mocks/send-sms/output.json
(1 hunks)integrations/clicksend/nango.yaml
(1 hunks)integrations/clicksend/schema.zod.ts
(1 hunks)integrations/clicksend/syncs/sms-history.md
(1 hunks)integrations/clicksend/syncs/sms-history.ts
(1 hunks)integrations/clicksend/tests/clicksend-fetch-account.test.ts
(1 hunks)integrations/clicksend/tests/clicksend-send-sms.test.ts
(1 hunks)integrations/clicksend/types.ts
(1 hunks)nango.yaml
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
`integrations/**/**.ts`: - Use TypeScript best practices and ensure typings are strictly defined. - Use comments to explain logic and link to external API documentation. - Place en...
integrations/**/**.ts
: - Use TypeScript best practices and ensure typings are strictly defined.
- Use comments to explain logic and link to external API documentation.
- Place endpoint URLs as comments above API requests.
- Avoid modifying arguments and prefer returning new values.
- Create a
types.ts
file containing typed third-party API responses.- Proxy calls should use retries (default:
10
).- Use
await nango.log()
instead ofconsole.log
for logging.- Use the
params
property in proxy calls instead of appending params onto the endpoint.- Use
nango.paginate
wherever possible for pagination.- Always use
ProxyConfiguration
for proxy request configurations.- Validate inputs/outputs using
zod
.- Ensure date inputs are valid and converted using
new Date()
to the provider's expected format.Syncs
- The
fetchData
function must be the default export and placed at the top.- Always paginate requests to ensure all records are retrieved.
- Avoid parallel requests to maintain the retry policy and prevent rate limits.
- Mapping logic should be in a dedicated function.
- Shared mapping logic should be stored in a
mappers
directory.- Mapper files should follow the
mappers/to-{entity}.ts
naming convention.- Avoid type casting and rely on TypeScript's type checking.
- If the sync is incremental, use
nango.lastSyncDate
.Actions
- The
runAction
function must be the default export and placed at the top.- Use
ActionError
only for specific error messages, otherwise rely on script failure.Example:
throw new nango.ActionError<ActionErrorResponse>({ message: 'Missing some parameter that will prevent the action from successfully running' });TypeScript Development Guidelines
Syncs
fetchData
must be the default export at the top of the file- Always paginate requests to retrieve all records
- Avoid parallelizing requests (defeats retry policy and rate limiting)
- Do not wrap syncs in try-catch blocks (Nango handles error reporting)
- Use dedicated mapper functions for data transformation:
- Place shared mappers in a
mappers
directory- Name files as
mappers/to-${entity}
(e.g.,mappers/to-employee.ts
)- Avoid type casting to leverage TypeScript benefits:
- For incremental syncs, use
nango.lastSyncDate
Actions
runAction
must be the default export at the top of the file- Only use
ActionError
for specific error messages:- Always return objects, not arrays
- Always define API calls using a typed
ProxyConfiguration
object with retries set to 3:- When implementing pagination in actions, always return a cursor-based response to allow users to paginate through results:
integrations/clicksend/tests/clicksend-fetch-account.test.ts
integrations/clicksend/types.ts
integrations/clicksend/mappers/to-sms.ts
integrations/clicksend/actions/send-sms.ts
integrations/clicksend/actions/fetch-account.ts
integrations/clicksend/schema.zod.ts
integrations/clicksend/mappers/to-account.ts
integrations/clicksend/tests/clicksend-send-sms.test.ts
integrations/clicksend/syncs/sms-history.ts
`integrations/**/nango.yaml`: - If `sync_type: full`, then the sync should also have `track_deletes: true`. - If the sync requires metadata, set `auto_start: false` and document th...
integrations/**/nango.yaml
: - Ifsync_type: full
, then the sync should also havetrack_deletes: true
.
If the sync requires metadata, set
auto_start: false
and document the metadata as an input innango.yaml
.Scopes should be explicitly documented.
If
sync_type: full
, then the sync should also havetrack_deletes: true
If the sync requires metadata, then the sync should be set to
auto_start: false
. The metadata should be documented as an input in the nango.yamlScopes should be documented
For optional properties in models, use the
?
suffix after the property nameEndpoints should be concise and simple, not necessarily reflecting the exact third-party API path
Model names and endpoint paths should not be duplicated within an integration
When adding a new integration, take care to not remove unrelated entries in the nango.yaml
For enum values in models, do not use quotes around the values
integrations/clicksend/nango.yaml
🧬 Code Graph Analysis (5)
integrations/clicksend/mappers/to-sms.ts (2)
integrations/clicksend/types.ts (1)
ClickSendSms
(1-30)integrations/clicksend/.nango/schema.ts (1)
Sms
(11-19)
integrations/clicksend/actions/send-sms.ts (3)
integrations/clicksend/.nango/schema.ts (2)
ClickSendSmsInput
(6-9)Sms
(11-19)integrations/clicksend/types.ts (1)
ClickSendSms
(1-30)integrations/clicksend/mappers/to-sms.ts (1)
toSms
(11-23)
integrations/clicksend/actions/fetch-account.ts (3)
integrations/clicksend/.nango/schema.ts (1)
Account
(21-31)integrations/clicksend/types.ts (1)
ClickSendAccount
(32-62)integrations/clicksend/mappers/to-account.ts (1)
toAccount
(15-27)
integrations/clicksend/mappers/to-account.ts (2)
integrations/clicksend/types.ts (1)
ClickSendAccount
(32-62)integrations/clicksend/.nango/schema.ts (1)
Account
(21-31)
demo-github-integration/syncs/github-issue-example.ts (2)
integrations/clicksend/syncs/sms-history.ts (1)
fetchData
(5-39).nango/schema.ts (1)
GithubIssue
(6-17)
🪛 markdownlint-cli2 (0.17.2)
integrations/clicksend/actions/fetch-account.md
22-22: Emphasis used instead of a heading
null
(MD036, no-emphasis-as-heading)
26-26: Emphasis used instead of a heading
null
(MD036, no-emphasis-as-heading)
integrations/clicksend/syncs/sms-history.md
30-30: Emphasis used instead of a heading
null
(MD036, no-emphasis-as-heading)
🪛 Biome (1.9.4)
integrations/clicksend/actions/fetch-account.ts
[error] 5-5: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
🪛 LanguageTool
integrations/clicksend/syncs/sms-history.md
[uncategorized] ~22-~22: You might be missing the article “the” here.
Context: ...ed_after parameter is less precise than cursor, as multiple records may share the same...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[style] ~24-~24: This phrase is redundant. Consider writing “point” or “time”.
Context: ...fetch records modified after a specific point in time.If not provided, all records are return...
(MOMENT_IN_TIME)
[uncategorized] ~26-~26: The grammatical number of this noun doesn’t look right. Consider replacing it.
Context: ...ray of string containing a list of your records IDs. The list will be filtered to inclu...
(AI_EN_LECTOR_REPLACEMENT_NOUN_NUMBER)
🪛 Gitleaks (8.21.2)
integrations/clicksend/mocks/nango/get/proxy/account/fetch-account/abd756729884886e6a97f89f107907c4d96aa044.json
66-66: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (25)
.nango/schema.ts (1)
6-17
: Interface structure looks correctThe GithubIssue interface properly defines all necessary fields with appropriate types for GitHub issue data storage. The use of proper TypeScript types including Date objects for timestamps follows best practices.
integrations/clicksend/mocks/send-sms/input.json (1)
1-4
: Mock input looks appropriateThe input JSON provides a valid test case with an international phone number format and a test message body, which aligns with the expected input for a send-SMS action.
integrations/clicksend/mocks/send-sms/output.json (1)
1-9
: Mock output structure looks correctThe output JSON correctly models a ClickSend SMS response with all the expected fields: unique ID, phone numbers, message content, status, and timestamps. This matches what we would expect from the ClickSend API.
integrations/clicksend/mocks/fetch-account/output.json (1)
1-11
: Account mock data looks appropriateThe account data structure includes all expected fields for a ClickSend account with proper formatting for identifiers, contact information, and numeric values like balance. This provides a good test case for the fetch-account action.
integrations/clicksend/tests/clicksend-fetch-account.test.ts (1)
5-19
: Test implementation looks solidThe test correctly initializes the NangoActionMock with proper parameters, executes the action with mock input, and validates the response against expected output. This ensures the fetch-account action functions correctly.
integrations/clicksend/mappers/to-sms.ts (1)
1-23
: Well-implemented mapper function with proper type definitions.This mapper function correctly transforms a
ClickSendSms
object from the API response into our standardized internalSms
model. The date conversion from UNIX timestamp to ISO string is properly implemented, and all required fields are mapped.integrations/clicksend/actions/fetch-account.md (1)
1-51
: Documentation is clear and comprehensive.The overall documentation provides excellent information about the fetch-account action, including its purpose, endpoint details, and response format.
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
22-22: Emphasis used instead of a heading
null(MD036, no-emphasis-as-heading)
26-26: Emphasis used instead of a heading
null(MD036, no-emphasis-as-heading)
integrations/clicksend/actions/send-sms.ts (1)
1-26
: Overall implementation follows best practices.The action follows best practices by using a typed
ProxyConfiguration
object, setting retries, providing API documentation, and using the mapper function to standardize the response format.integrations/clicksend/actions/fetch-account.ts (1)
6-6
: Documentation link placement is correct.
The API reference URL sits immediately above the proxy call, aiding future maintainers.integrations/clicksend/mappers/to-account.ts (1)
15-27
: Mapping logic is correct and well-structured.
ThetoAccount
function properly converts and formats fields (e.g.,user_id
→id
, concatenating names) and aligns with the internalAccount
schema.integrations/clicksend/syncs/sms-history.ts (3)
8-10
: Excellent handling of lastSyncDate conversionThe conversion from date to Unix timestamp is correctly implemented, ensuring proper pagination from the last sync point.
12-26
: Well-configured proxy with proper documentation and paginationThe proxy configuration properly includes:
- API endpoint documentation link
- Correctly configured pagination settings
- Appropriate retry count (10)
- Well-structured parameters
This follows best practices for Nango integrations.
28-38
: Good implementation of pagination and data processingThe code correctly:
- Uses
nango.paginate
for efficient pagination- Validates response structure
- Maps data using the dedicated mapper function
- Only saves when there's data to save
This is an optimal implementation of the sync pattern.
integrations/clicksend/types.ts (2)
1-30
: Comprehensive SMS type definitionThe
ClickSendSms
interface is well-structured with:
- Proper typing for all fields
- Comprehensive status union type
- Clear documentation for optional fields
- Appropriate handling of varying field types (string | null, etc.)
This provides strong typing for the API integration.
32-62
: Well-defined Account interface with placeholders for future expansionThe
ClickSendAccount
interface is thorough and includes appropriate documentation for fields that may need expansion in the future. The use ofRecord<string, unknown>
with explanatory comments is a good approach for fields with unknown structure.integrations/clicksend/schema.zod.ts (3)
4-7
: Minimal and effective input validationThe input schema correctly validates the required fields (
to
andbody
) for sending an SMS.
9-27
: Thorough SMS schema with well-defined status literalsThe SMS schema properly:
- Defines all required fields with appropriate types
- Uses a union of literals for the status field
- Includes timestamp fields with string validation
This ensures strong validation for SMS data objects.
29-39
: Properly structured account schemaThe account schema correctly defines all required fields with appropriate string validations.
integrations/clicksend/nango.yaml (2)
3-20
: Actions configuration looks solid
Thesend-sms
andfetch-account
actions are well-defined with method, path, input/output types, and grouping.
21-33
: Sync configuration is correct
The incrementalsms-history
sync is properly defined withsync_type: incremental
,track_deletes: false
, scheduling, andauto_start: true
.integrations/clicksend/.nango/schema.json (1)
33-35
: Verify completeness ofSms.status
enum
Please confirm whether"SUCCESS"
is a valid message-level status from ClickSend. If so, update the enum to include"SUCCESS"
; otherwise adjust mocks/tests to use a supported value.integrations/clicksend/.nango/schema.ts (1)
16-16
: Align TypeScript union with JSON schema
If you decide to add"SUCCESS"
to the JSON schema, update this union accordingly:- status: 'QUEUED' | 'COMPLETED' | 'SCHEDULED' | 'WAIT_APPROVAL' | 'FAILED' | 'CANCELLED' | 'CANCELLED_AFTER_REVIEW' | 'RECEIVED' | 'SENT'; + status: 'QUEUED' | 'COMPLETED' | 'SCHEDULED' | 'WAIT_APPROVAL' | 'FAILED' | 'CANCELLED' | 'CANCELLED_AFTER_REVIEW' | 'RECEIVED' | 'SENT' | 'SUCCESS';flows.yaml (3)
3434-3452
: Integration Structure: Actions Block Looks Correct
Theclicksend
integration’sactions
section is well-structured, with clear endpoint definitions (/sms/send
,/account
), versioning, groups, and matching input/output types. Indentation and naming conventions align with existing templates.
3453-3466
: Sync Configuration: Verify Incremental Sync Details
Thesms-history
sync is marked asincremental
and scheduled every half hour. Please confirm that the underlying sync implementation defines and uses a cursor field (e.g.,createdAt
or pagination token) so the resume logic works as intended. Ensure the YAML properties here match yournango.paginate
call and any custom parameters insms-history.ts
.
3467-3490
: Models Block: Confirm Field Mappings
TheClickSendSmsInput
,Sms
, andAccount
models enumerate all expected properties. Double-check that these fields exactly mirror the API response keys and your JSON schema inintegrations/clicksend/.nango/schema.json
to prevent runtime validation errors.
...nd/mocks/nango/get/proxy/account/fetch-account/abd756729884886e6a97f89f107907c4d96aa044.json
Outdated
Show resolved
Hide resolved
...ksend/mocks/nango/post/proxy/sms/send/send-sms/ef821ad18258311a60ec6e84cd2316729825303d.json
Outdated
Show resolved
Hide resolved
Following the changes introduced here, where the base URL was updated (removing /v3 from the base URL because it isn't part of it), I'm about to make another commit. This next one will include small adjustments to add /v3 to the sync and action endpoints, along with a few additional fixes suggested by CodeRabbitAI. |
…t endpoints and mocks
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: 2
♻️ Duplicate comments (1)
integrations/clicksend/actions/send-sms.ts (1)
26-33
: LGTM! Added error handling for missing response data.The error handling for missing response data has been properly implemented.
🧹 Nitpick comments (5)
integrations/clicksend/actions/fetch-account.ts (2)
5-5
: Consider using undefined instead of void for input parameter typeThe static analysis tool flagged the use of
void
as a type parameter. In TypeScript,void
is typically used for return types that don't return a value, not as a parameter type.-export default async function runAction(nango: NangoAction, _input?: void): Promise<Account> { +export default async function runAction(nango: NangoAction, _input?: undefined): Promise<Account> {🧰 Tools
🪛 Biome (1.9.4)
[error] 5-5: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
13-13
: Consider adding type validation for the API responseWhile the typings provide structure, there's no runtime validation of the API response. Consider using zod to validate the structure of the API response before processing it.
import { clickSendAccountSchema } from '../schema.zod.js'; // Replace line 13 with: const data = response.data.data; const validationResult = clickSendAccountSchema.safeParse(data); if (!validationResult.success) { await nango.log('Failed to validate account data', { error: validationResult.error }); throw new Error('Invalid account data received from ClickSend API'); } const clickSendAccount: ClickSendAccount = validationResult.data;integrations/clicksend/mappers/to-sms.ts (1)
19-22
: Add clarification about identical timestamp fields.The
createdAt
andupdatedAt
fields are both derived from the samedate
property. Consider adding a comment to clarify that this is intentional and that ClickSend doesn't provide separate creation and update timestamps.// UNIX timestamp to ISO date createdAt: new Date(message.date * 1000).toISOString(), + // ClickSend doesn't provide separate update timestamps, using the same date updatedAt: new Date(message.date * 1000).toISOString()
integrations/clicksend/syncs/sms-history.md (2)
22-22
: Fix grammatical error in description.There's a missing "the" article before "cursor".
-modified_after parameter is less precise than cursor, as multiple records may share the same +modified_after parameter is less precise than the cursor, as multiple records may share the same🧰 Tools
🪛 LanguageTool
[uncategorized] ~22-~22: You might be missing the article “the” here.
Context: ...ed_after parameter is less precise than cursor, as multiple records may share the same...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
24-24
: Add space after period in sentence.There's a missing space between sentences.
-fetch records modified after a specific point in time.If not provided, all records are returned. +fetch records modified after a specific point in time. If not provided, all records are returned.🧰 Tools
🪛 LanguageTool
[style] ~24-~24: This phrase is redundant. Consider writing “point” or “time”.
Context: ...fetch records modified after a specific point in time.If not provided, all records are return...(MOMENT_IN_TIME)
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
flows.yaml
(1 hunks)integrations/clicksend/.nango/schema.json
(1 hunks)integrations/clicksend/.nango/schema.ts
(1 hunks)integrations/clicksend/actions/fetch-account.ts
(1 hunks)integrations/clicksend/actions/send-sms.md
(1 hunks)integrations/clicksend/actions/send-sms.ts
(1 hunks)integrations/clicksend/mappers/to-sms.ts
(1 hunks)integrations/clicksend/mocks/nango/get/proxy/v3/account/fetch-account/6dc41d02e1c27b5788531bfdf2583a8cc821a4e0.json
(1 hunks)integrations/clicksend/mocks/nango/post/proxy/v3/sms/send/send-sms/e2c198d02ddeb067302cec37ce1d85b60a4e4e7e.json
(1 hunks)integrations/clicksend/nango.yaml
(1 hunks)integrations/clicksend/schema.zod.ts
(1 hunks)integrations/clicksend/syncs/sms-history.md
(1 hunks)integrations/clicksend/syncs/sms-history.ts
(1 hunks)integrations/clicksend/types.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- integrations/clicksend/mocks/nango/post/proxy/v3/sms/send/send-sms/e2c198d02ddeb067302cec37ce1d85b60a4e4e7e.json
- integrations/clicksend/mocks/nango/get/proxy/v3/account/fetch-account/6dc41d02e1c27b5788531bfdf2583a8cc821a4e0.json
- flows.yaml
🚧 Files skipped from review as they are similar to previous changes (6)
- integrations/clicksend/syncs/sms-history.ts
- integrations/clicksend/types.ts
- integrations/clicksend/.nango/schema.ts
- integrations/clicksend/nango.yaml
- integrations/clicksend/schema.zod.ts
- integrations/clicksend/.nango/schema.json
🧰 Additional context used
📓 Path-based instructions (1)
`integrations/**/**.ts`: - Use TypeScript best practices and ensure typings are strictly defined. - Use comments to explain logic and link to external API documentation. - Place en...
integrations/**/**.ts
: - Use TypeScript best practices and ensure typings are strictly defined.
- Use comments to explain logic and link to external API documentation.
- Place endpoint URLs as comments above API requests.
- Avoid modifying arguments and prefer returning new values.
- Create a
types.ts
file containing typed third-party API responses.- Proxy calls should use retries (default:
10
).- Use
await nango.log()
instead ofconsole.log
for logging.- Use the
params
property in proxy calls instead of appending params onto the endpoint.- Use
nango.paginate
wherever possible for pagination.- Always use
ProxyConfiguration
for proxy request configurations.- Validate inputs/outputs using
zod
.- Ensure date inputs are valid and converted using
new Date()
to the provider's expected format.Syncs
- The
fetchData
function must be the default export and placed at the top.- Always paginate requests to ensure all records are retrieved.
- Avoid parallel requests to maintain the retry policy and prevent rate limits.
- Mapping logic should be in a dedicated function.
- Shared mapping logic should be stored in a
mappers
directory.- Mapper files should follow the
mappers/to-{entity}.ts
naming convention.- Avoid type casting and rely on TypeScript's type checking.
- If the sync is incremental, use
nango.lastSyncDate
.Actions
- The
runAction
function must be the default export and placed at the top.- Use
ActionError
only for specific error messages, otherwise rely on script failure.Example:
throw new nango.ActionError<ActionErrorResponse>({ message: 'Missing some parameter that will prevent the action from successfully running' });TypeScript Development Guidelines
Syncs
fetchData
must be the default export at the top of the file- Always paginate requests to retrieve all records
- Avoid parallelizing requests (defeats retry policy and rate limiting)
- Do not wrap syncs in try-catch blocks (Nango handles error reporting)
- Use dedicated mapper functions for data transformation:
- Place shared mappers in a
mappers
directory- Name files as
mappers/to-${entity}
(e.g.,mappers/to-employee.ts
)- Avoid type casting to leverage TypeScript benefits:
- For incremental syncs, use
nango.lastSyncDate
Actions
runAction
must be the default export at the top of the file- Only use
ActionError
for specific error messages:- Always return objects, not arrays
- Always define API calls using a typed
ProxyConfiguration
object with retries set to 3:- When implementing pagination in actions, always return a cursor-based response to allow users to paginate through results:
integrations/clicksend/actions/send-sms.ts
integrations/clicksend/mappers/to-sms.ts
integrations/clicksend/actions/fetch-account.ts
🧬 Code Graph Analysis (3)
integrations/clicksend/actions/send-sms.ts (4)
integrations/clicksend/.nango/schema.ts (2)
ClickSendSendSmsInput
(6-9)Sms
(11-19)integrations/clicksend/schema.zod.ts (1)
clickSendSendSmsInputSchema
(4-7)integrations/clicksend/types.ts (1)
ClickSendSms
(1-30)integrations/clicksend/mappers/to-sms.ts (1)
toSms
(11-23)
integrations/clicksend/mappers/to-sms.ts (2)
integrations/clicksend/types.ts (1)
ClickSendSms
(1-30)integrations/clicksend/.nango/schema.ts (1)
Sms
(11-19)
integrations/clicksend/actions/fetch-account.ts (3)
integrations/clicksend/.nango/schema.ts (1)
Account
(21-31)integrations/clicksend/types.ts (1)
ClickSendAccount
(32-62)integrations/clicksend/mappers/to-account.ts (1)
toAccount
(15-27)
🪛 Biome (1.9.4)
integrations/clicksend/actions/fetch-account.ts
[error] 5-5: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
🪛 markdownlint-cli2 (0.17.2)
integrations/clicksend/actions/send-sms.md
22-22: Emphasis used instead of a heading
null
(MD036, no-emphasis-as-heading)
integrations/clicksend/syncs/sms-history.md
30-30: Emphasis used instead of a heading
null
(MD036, no-emphasis-as-heading)
🪛 LanguageTool
integrations/clicksend/syncs/sms-history.md
[uncategorized] ~22-~22: You might be missing the article “the” here.
Context: ...ed_after parameter is less precise than cursor, as multiple records may share the same...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[style] ~24-~24: This phrase is redundant. Consider writing “point” or “time”.
Context: ...fetch records modified after a specific point in time.If not provided, all records are return...
(MOMENT_IN_TIME)
🔇 Additional comments (5)
integrations/clicksend/actions/fetch-account.ts (2)
7-11
: The endpoint should include /v3 explicitlyAccording to the PR objectives, a recent update to the base URL removed
/v3
, requiring endpoints to explicitly include it. However, I notice your endpoint already includes/v3/account
, which means this implementation already incorporates the planned adjustment.
7-16
: The function follows appropriate error handling patternsThe code correctly uses the proxy method with retries set to 3, allowing Nango's built-in error handling to manage failures. The response structure and mapping logic are properly implemented.
integrations/clicksend/mappers/to-sms.ts (1)
25-50
: LGTM! Well-structured status mapping function.The status mapping function provides a robust handling of all possible status values with appropriate error handling for unknown values.
integrations/clicksend/actions/send-sms.ts (2)
6-8
: LGTM! Proper input validation implemented.The input validation using Zod schema follows the coding guidelines and ensures input data correctness.
18-24
: LGTM! Proper proxy configuration setup.The proxy configuration correctly includes retries and the API endpoint documentation URL as a comment.
Describe your changes
Description:
This PR introduces the ClickSend integration template to the
integration-templates
repository.Summary of changes:
README.md
file with setup instructions.Issue ticket number and link
Checklist before requesting a review (skip if just adding/editing APIs & templates)
Only the
sms-history
sync does not yet have a test file.This is because it uses the
paginate
, which requires the provider to be fully registered first.Currently, since ClickSend is not yet added to the live providers, it causes a provider existence validation error.
I plan to add the test for
sms-history
as soon as the provider is merged.All other actions and syncs interact via direct proxy endpoints, which do not require provider existence validation, allowing them to have working tests already.
retries
nango.paginate
call is used instead of awhile (true)
loopnango.yaml
hasauto_start: false
full
sync thentrack_deletes: true
is set