-
Notifications
You must be signed in to change notification settings - Fork 4
Add webhooks support #3
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
Conversation
WalkthroughThis pull request implements a broad set of enhancements and refactorings. The changes update build configurations to add Kotlin Symbol Processing, Room, WorkManager, and Ktor dependencies while defining a Room schema. The app’s architecture is refactored—from using ServerService and GeneralSettings to employing OrchestratorService alongside new Koin modules. New functionality for call event handling, webhook management (including routes, DAO, models, signing, and a background worker), and settings configuration is introduced. In addition, several new UI resources and preference screens have been added or modified to support these features. Changes
Sequence Diagram(s)sequenceDiagram
participant Phone as Phone (Broadcast)
participant Receiver as CallsReceiver
participant Service as CallsService
participant Webhook as WebHooksService
Phone->>Receiver: Broadcast PHONE_STATE_CHANGED
Receiver->>Service: onReceive(intent with phone state & number)
Service->>Webhook: processEvent(CallEvent)
Webhook-->>Service: Emit webhook event (call-related)
sequenceDiagram
participant Worker as SendWebhookWorker
participant Storage as TemporaryStorage
participant Plugin as PayloadSigningPlugin
participant HTTP as HttpClient
Worker->>Storage: Retrieve payload (if any)
Worker->>Plugin: Sign payload (attach headers)
Plugin->>HTTP: Send POST request with signed payload
HTTP-->>Worker: Return response (Success/Failure/Retry)
Worker->>Storage: Remove payload on final outcome
Possibly related PRs
Tip ⚡💬 Agentic Chat (Pro Plan, General Availability)
🪧 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
CodeRabbit Configuration File (
|
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: 16
🔭 Outside diff range comments (1)
app/src/main/res/drawable/ic_retry.xml (1)
14-14:⚠️ Potential issueRemove Stray Artifact at End of File
Line 14 appears to be an extraneous number that does not belong to the XML content. This stray text might cause XML parsing issues. Please remove it to ensure the file is valid.
Proposed change:
-14
🧹 Nitpick comments (35)
app/src/main/res/drawable-notnight/ic_signing_key.xml (2)
1-7: Review of Vector Drawable AttributesThe vector drawable is correctly set up with a width and height of 24dp, and matching viewport dimensions. One point to consider is the use of
android:tint="@android:color/black"at the vector level; this will apply a tint over any color defined in the<path>elements. Please verify that this is the desired behavior—if you intend to preserve the white fill defined in the path, you may need to remove or adjust the tint attribute.
8-11: Review of Path ElementThe
<path>element correctly provides a fill color (@android:color/white) and a detailedandroid:pathDatadescription for the signing key icon. For future maintainability, consider adding a short comment describing the design intent or origin of the path data in case revisions are needed.app/src/main/res/drawable-notnight/ic_retry.xml (3)
1-7: Vector Drawable Declaration and Attribute Usage
The vector is declared correctly with appropriate dimensions, viewport settings, and auto-mirroring enabled. Please verify that using a hardcoded tint (@android:color/black) over the default white fill is intentional and aligns with your design, especially for different themes.
9-11: Path Element and Icon Design
The<path>element is well-defined with itsfillColorset to white and thepathDataoutlining the icon. Ensure that the icon’s shape and color match your design specifications. Consider leveraging theme attributes instead of fixed colors if future theme support or customization is anticipated.
12-14: Duplicate Resources Management
Since there is a similaric_retry.xmlin thedrawable/directory, confirm that maintaining duplicate files (for different themes or configurations) is the preferred approach. Otherwise, you might consolidate these into a single resource that adapts to different configurations using resource qualifiers or theme attributes to reduce maintenance overhead.app/src/main/res/drawable/ic_retry.xml (1)
1-7: Vector Declaration and Attributes VerificationThe vector element is well-formed with clear definitions for width, height, autoMirroring, tint, and viewport dimensions. The use of
android:tint="#FFFFFF"combined with the path’s own fill color (@android:color/white) is acceptable, though you might consider whether applying a global tint is intended or could be redundant in your design context.app/src/main/res/drawable/ic_no_internet.xml (2)
1-6: Vector Container Setup Looks Solid
The vector element is correctly defined with the proper XML namespace, dimensions (24dp width/height), tint, and viewport attributes. This configuration should render the icon at the intended size.
8-10: Path Element Definition is Clear
The path element uses well-formedandroid:pathDatato describe the "no internet" icon shape and sets the fill color appropriately to white. Make sure that the combined path data (which contains multiple move and line commands) precisely matches the design specifications.app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt (1)
3-5: Consider enhancing theCallEventPayloadclassThe class implementation is clean, but consider the following improvements:
- Add KDoc documentation to explain the purpose of this class and how it's used in the webhook system
- Evaluate if
phoneNumbershould be nullable - if it's a required field for meaningful call events, consider making it non-nullable- Consider whether additional fields might be useful in a call event payload (e.g., timestamp, call type, call duration)
+/** + * Data class representing the payload for call-related webhook events. + * Contains information about the phone number associated with the call. + */ data class CallEventPayload( + /** The phone number associated with the call event, may be null if unavailable */ val phoneNumber: String?, )app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt (2)
16-43: Handle ForegroundServiceStartNotAllowedException properly but remove commented logging codeThe method correctly handles the specific Android S+ exception when trying to start a foreground service from the background. However, there's commented-out logging code that should be either implemented or removed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e is ForegroundServiceStartNotAllowedException ) { Log.e( "OrchestratorService", "Can't start foreground services while the app is running in the background" ) -// logsSvc.insert( -// LogEntry.Priority.WARN, -// MODULE_NAME, -// "Can't start foreground services while the app is running in the background" -// ) return }
16-43: Consider a more detailed error handling strategyThe current implementation catches all
Throwabletypes but only specifically handlesForegroundServiceStartNotAllowedException. For improved error handling:
- Consider catching more specific exceptions that might occur during service startup
- Add logging for other exception types before rethrowing
- Consider reporting errors to a monitoring system
try { serverSvc.start(context) - } catch (e: Throwable) { + } catch (e: Exception) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e is ForegroundServiceStartNotAllowedException ) { Log.e( "OrchestratorService", "Can't start foreground services while the app is running in the background" ) return + } else { + Log.e("OrchestratorService", "Failed to start server service", e) } throw e }app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt (4)
9-11: Add validation for key parameterThe
putmethod doesn't validate thekeyparameter. Consider adding validation to ensure the key is not empty or contains invalid characters.fun put(key: String, value: String) { + require(key.isNotBlank()) { "Key cannot be empty" } storage.set(PREFIX + key, value) }
13-15: Add validation for key parameterSimilar to the
putmethod, thegetmethod should also validate the key parameter.fun get(key: String): String? { + require(key.isNotBlank()) { "Key cannot be empty" } return storage.get(PREFIX + key) }
17-19: Add validation for key parameterThe
removemethod should validate the key parameter as well.fun remove(key: String) { + require(key.isNotBlank()) { "Key cannot be empty" } storage.remove(PREFIX + key) }
21-23: Make PREFIX a constantThe
PREFIXproperty should be declared as aconstsince it's a compile-time constant. This would improve performance slightly as the value can be inlined at compile time.companion object { - private val PREFIX = "storage." + private const val PREFIX = "storage." }app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt (2)
24-26: Add validation for the response in GET routeConsider validating that the response from
webHooksService.select()is not null before responding to ensure a more robust implementation.get { + try { val webhooks = webHooksService.select(EntitySource.Local) + if (webhooks == null) { + call.respond(HttpStatusCode.NotFound) + return@get + } call.respond(webhooks) + } catch (e: Exception) { + call.respond(HttpStatusCode.InternalServerError, mapOf("error" to e.message)) + } }
27-32: Validate webhook in POST routeAdd validation for the webhook object received in the POST route to ensure it meets the required format and contains all necessary fields.
post { + try { val webhook = call.receive<WebHookDTO>() + + // Basic validation + if (webhook.url.isNullOrBlank()) { + call.respond(HttpStatusCode.BadRequest, mapOf("error" to "URL cannot be empty")) + return@post + } + val updated = webHooksService.replace(EntitySource.Local, webhook) call.respond(HttpStatusCode.Created, updated) + } catch (e: Exception) { + call.respond(HttpStatusCode.InternalServerError, mapOf("error" to e.message)) + } }app/src/main/java/app/callgate/android/modules/webhooks/Module.kt (1)
10-10: Consider making the MODULE_NAME constant private or internal.This constant appears to be used for identification purposes, but it's currently defined with module-level visibility. If it's only used within this module, consider restricting its visibility.
-val MODULE_NAME = "webhooks" +private const val MODULE_NAME = "webhooks"app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt (1)
10-10: Consider making the MODULE_NAME constant private or internal.Similar to the webhooks module, this constant appears to be for identification purposes but has module-level visibility. If it's only used internally, consider restricting its visibility.
-val MODULE_NAME = "orchestrator" +private const val MODULE_NAME = "orchestrator"app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEventDTO.kt (1)
3-9: Consider refining the payload type for better type safetyThe data class structure is good overall, with appropriate non-nullable fields for tracking webhook events. However, using
Anyfor the payload field sacrifices type safety and might lead to issues with serialization/deserialization.Consider alternatives like:
- val payload: Any, + val payload: Map<String, Any>,Or using generics:
-data class WebHookEventDTO( +data class WebHookEventDTO<T>( val id: String, val webhookId: String, val event: WebHookEvent, val deviceId: String, - val payload: Any, + val payload: T, )Additionally, consider documenting the expected payload structure for different event types to aid consumers of these webhooks.
app/src/main/java/app/callgate/android/modules/webhooks/db/WebHook.kt (1)
8-15: Consider adding URL validation.The
WebHookentity is well-structured with appropriate Room annotations. All the essential properties for a webhook are present.Consider adding validation for the
urlproperty to ensure it's properly formatted before storing it in the database. Additionally, if the webhooks need authentication, you might want to add relevant properties for that.@Entity data class WebHook( @PrimaryKey val id: String, val url: String, val event: WebHookEvent, val source: EntitySource, ) { + // This could be a companion object validation method + companion object { + fun validateUrl(url: String): Boolean { + return android.util.Patterns.WEB_URL.matcher(url).matches() + } + } }app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt (1)
10-12: Consider adding a default value or initialization mechanism for deviceIdThe
deviceIdproperty is added as nullable without a default value generation mechanism, unlikepasswordwhich has a fallback generation. Since this appears to be used for webhook functionality, consider whether it should have a default value (like a UUID) or if it's intentionally left unset until explicitly configured.app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt (1)
15-33: Consider refactoring preference dialog handling and adding input validationThe current implementation handles each preference separately with very similar code. Consider refactoring to reduce duplication:
- For retry count, consider adding min/max validation or using a NumberPickerPreference
- For signing key, consider adding format validation based on expected key format
- The duplicated setSelectAllOnFocus logic could be extracted to a helper method
- override fun onDisplayPreferenceDialog(preference: Preference) { - if (preference.key == "webhooks.retry_count") { - (preference as EditTextPreference).setOnBindEditTextListener { - it.inputType = InputType.TYPE_CLASS_NUMBER - it.setSelectAllOnFocus(true) - it.selectAll() - } - } - - if (preference.key == "webhooks.signing_key") { - (preference as EditTextPreference).setOnBindEditTextListener { - it.inputType = InputType.TYPE_CLASS_TEXT - it.setSelectAllOnFocus(true) - it.selectAll() - } - } - - super.onDisplayPreferenceDialog(preference) - } + override fun onDisplayPreferenceDialog(preference: Preference) { + when (preference.key) { + "webhooks.retry_count" -> { + (preference as EditTextPreference).setOnBindEditTextListener { + it.inputType = InputType.TYPE_CLASS_NUMBER + // Optional: Add min/max validation + // it.filters = arrayOf(InputFilter.LengthFilter(3), MinMaxFilter(1, 100)) + configureEditText(it) + } + } + "webhooks.signing_key" -> { + (preference as EditTextPreference).setOnBindEditTextListener { + it.inputType = InputType.TYPE_CLASS_TEXT + configureEditText(it) + } + } + } + + super.onDisplayPreferenceDialog(preference) + } + + private fun configureEditText(editText: EditText) { + editText.setSelectAllOnFocus(true) + editText.selectAll() + }app/schemas/app.callgate.android.modules.db.AppDatabase/1.json (1)
1-52: Database schema looks good with some potential improvements.This is a well-structured Room database schema for storing webhook configurations. The WebHook entity contains all the necessary fields for managing webhook integrations.
A few considerations for future optimization:
No indexes are defined beyond the primary key. Consider adding indexes on
eventand/orsourcefields if you anticipate frequently querying by these fields.The primary key
idis not set to auto-generate, which means your application code must handle generating unique IDs before insertion.Consider whether you need uniqueness constraints on the combination of
url,event, andsourceto prevent duplicate webhook configurations.app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt (1)
24-29: Remove commented debug code.Consider removing the commented logging code if it's no longer needed. If it's kept for future debugging, add a comment explaining why it's being preserved.
-// Log.d( -// "CallsReceiver", -// "Extras: ${ -// intent.extras?.keySet()?.joinToString { "${it}: ${intent.extras?.get(it)}" } -// }" -// )app/src/main/java/app/callgate/android/modules/calls/CallsService.kt (1)
40-40: Appropriately suppressing deprecation warnings.The @Suppress("DEPRECATION") annotations are correctly applied to methods using deprecated APIs. However, consider adding a comment explaining why these deprecated APIs are still being used and any plans for future migration.
@SuppressLint("MissingPermission") -@Suppress("DEPRECATION") +@Suppress("DEPRECATION") // Using deprecated API until migration to newer TelecomManager APIs is complete fun getCall(): CallDetails {Also applies to: 73-73
app/src/main/res/xml/webhooks_preferences.xml (2)
11-16: Consider adding input validation for retry count.The retry count is currently accepted as a free-form text input without validation. Consider adding constraints to ensure only positive integers within a reasonable range are accepted.
You could implement a custom preference with input validation or add runtime validation in the associated PreferenceFragment's onPreferenceChangeListener.
18-23: Inconsistent key attribute namespace.The signing key preference uses
app:keywhile other preferences useandroid:key. Standardize on one approach for consistency.<EditTextPreference android:icon="@drawable/ic_signing_key" app:enableCopying="true" - app:key="webhooks.signing_key" + android:key="webhooks.signing_key" app:title="@string/signing_key" app:useSimpleSummaryProvider="true" />app/src/main/java/app/callgate/android/modules/server/WebService.kt (1)
163-163: Appropriate use of @Suppress annotation for deprecated method.The
@Suppress("DEPRECATION")annotation is properly used before calling the deprecatedstopForeground(true)method. Consider updating to the non-deprecated version in a future release.In a future update, consider replacing
stopForeground(true)with the newer API:-@Suppress("DEPRECATION") -stopForeground(true) +stopForeground(STOP_FOREGROUND_REMOVE)app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt (1)
16-18: Consider adding a method to regenerate the signing key.While the current implementation works well for initial key generation, users might want to regenerate the key for security purposes.
val signingKey: String get() = storage.get<String>(SIGNING_KEY) ?: NanoId.generate(size = 8).also { storage.set(SIGNING_KEY, it) } +fun regenerateSigningKey(): String { + val newKey = NanoId.generate(size = 8) + storage.set(SIGNING_KEY, newKey) + return newKey +}app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (2)
46-47: Commented-out logging usage.
If you’re intentionally removing logging, consider deleting these lines to keep the code clean. Otherwise, re-enable them for debugging.-// private val logsSvc: LogsService by inject()
121-156: Sealed Result overshadowing Worker’s Result.
The localResultclass name could be confused withListenableWorker.Result. Consider renaming the sealed class to avoid shadowing, e.g.SendResult.-sealed class Result { +sealed class SendResult { object Success : SendResult() class Failure(val error: String) : SendResult() class Retry(val reason: String) : SendResult() }app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt (3)
44-53: Improve error message for ID validation.The error message for the ID validation is generic. Consider providing more context in the error message to help with debugging.
fun sync(source: EntitySource, webHooks: List<WebHookDTO>) { webHooksDao.replaceAll(source, webHooks.map { WebHook( - id = requireNotNull(it.id) { "ID is required for sync" }, + id = requireNotNull(it.id) { "Webhook ID is required for synchronization" }, url = it.url, event = it.event, source = source, ) }) }
55-65: Enhance URL validation to support more local development scenarios.The current URL validation only allows HTTPS URLs or HTTP URLs with exactly "127.0.0.1" as the host. Consider extending this to support other local development hostnames like "localhost" or the entire 127.0.0.0/8 subnet.
fun replace(source: EntitySource, webHook: WebHookDTO): WebHookDTO { - if (!URLUtil.isHttpsUrl(webHook.url) - && !(URLUtil.isHttpUrl(webHook.url) && URL(webHook.url).host == "127.0.0.1") - ) { - throw IllegalArgumentException("url must start with https:// or http://127.0.0.1") + val url = URL(webHook.url) + if (!URLUtil.isHttpsUrl(webHook.url) && + !(URLUtil.isHttpUrl(webHook.url) && ( + url.host == "127.0.0.1" || + url.host == "localhost" || + url.host.startsWith("127.") + )) + ) { + throw IllegalArgumentException("URL must use HTTPS or be a local HTTP URL (localhost, 127.x.x.x)") } if (webHook.event !in WebHookEvent.entries) { throw IllegalArgumentException( "Unsupported event" ) }
82-84: Add error handling for deleted entities.The
deletemethod doesn't handle the case where the ID doesn't exist. Consider adding error handling or documentation about expected behavior.+ /** + * Deletes a webhook by its source and ID. + * If the webhook doesn't exist, this operation is a no-op. + * + * @param source The source of the webhook + * @param id The ID of the webhook to delete + */ fun delete(source: EntitySource, id: String) { webHooksDao.delete(source, id) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (50)
app/build.gradle.kts(4 hunks)app/schemas/app.callgate.android.modules.db.AppDatabase/1.json(1 hunks)app/src/main/AndroidManifest.xml(1 hunks)app/src/main/java/app/callgate/android/App.kt(2 hunks)app/src/main/java/app/callgate/android/domain/EntitySource.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsService.kt(3 hunks)app/src/main/java/app/callgate/android/modules/calls/events/CallEvent.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/Converters.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/notifications/NotificationsService.kt(2 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/ServerService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt(2 hunks)app/src/main/java/app/callgate/android/modules/server/WebService.kt(6 hunks)app/src/main/java/app/callgate/android/modules/server/routes/CallsRoutes.kt(2 hunks)app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt(1 hunks)app/src/main/java/app/callgate/android/modules/settings/Module.kt(2 hunks)app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHook.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookDTO.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEvent.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEventDTO.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSingingPlugin.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt(1 hunks)app/src/main/java/app/callgate/android/ui/HomeFragment.kt(5 hunks)app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt(1 hunks)app/src/main/res/drawable-notnight/ic_no_internet.xml(1 hunks)app/src/main/res/drawable-notnight/ic_retry.xml(1 hunks)app/src/main/res/drawable-notnight/ic_signing_key.xml(1 hunks)app/src/main/res/drawable-notnight/ic_webhook.xml(1 hunks)app/src/main/res/drawable/ic_no_internet.xml(1 hunks)app/src/main/res/drawable/ic_retry.xml(1 hunks)app/src/main/res/drawable/ic_signing_key.xml(1 hunks)app/src/main/res/drawable/ic_webhook.xml(1 hunks)app/src/main/res/drawable/notif_server.xml(1 hunks)app/src/main/res/drawable/notif_webhook.xml(1 hunks)app/src/main/res/values/strings.xml(2 hunks)app/src/main/res/xml/root_preferences.xml(1 hunks)app/src/main/res/xml/webhooks_preferences.xml(1 hunks)build.gradle.kts(1 hunks)
🔇 Additional comments (97)
app/src/main/res/drawable/ic_retry.xml (1)
9-13: Path Element ValidationThe
<path>element is configured correctly with a fill color reference and detailedandroid:pathDatathat defines the retry icon's shape. Ensure that the path data accurately reflects the visual design you intend for a retry icon.app/src/main/res/drawable/ic_no_internet.xml (1)
12-13: File Closure and Overall Consistency
The closing tag for the vector is correctly placed, ensuring the XML is well-formed. Overall, the file structure and attributes follow standard practices for vector drawables.app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt (1)
11-15: Good use of dependency injectionThe constructor properly uses dependency injection to receive its dependencies, which helps with testability and loose coupling.
app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt (1)
6-8: Good use of dependency injectionThe class properly receives its dependency via constructor injection, following good design practices.
app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt (1)
14-21: Good use of dependency injection and clean route registrationThe class uses dependency injection correctly and implements a clean route registration strategy.
app/src/main/java/app/callgate/android/domain/EntitySource.kt (1)
1-6: Solid Implementation of EntitySource Enum.
The new enum cleanly distinguishes betweenLocalandCloudentity sources, which will help in categorizing webhook origins and other entity types. The code is clear and follows Kotlin conventions.app/src/main/res/drawable-notnight/ic_no_internet.xml (1)
1-13: Clear and Consistent Icon Design for No Internet.
The vector drawable is well-defined with proper dimensions and tinting. The use of a black tint with a white fill achieves a strong contrast, but please ensure that the icon displays correctly in various themes (especially for night mode variations) if needed.app/src/main/res/drawable/notif_server.xml (1)
1-24: Detailed Notification Icon Vector.
This new drawable resource for notifications is comprehensive with multiple<path>elements forming a detailed icon. Verify that the complexity of the vector does not impact rendering performance on lower-end devices and that it scales well across different screen densities.app/src/main/res/drawable-notnight/ic_webhook.xml (1)
1-13: Appropriate Webhook Icon Representation.
The webhook icon is clearly defined with a single<path>and appropriate tinting, supporting the new webhooks functionality. Ensure that its visual style aligns with the overall UI design and accessibility standards.app/src/main/res/drawable/ic_signing_key.xml (1)
1-13: Well-Crafted Signing Key Icon Vector.
The signing key vector drawable is implemented with clear dimensions and a consistent white tint, making it suitable for use in different themes. Confirm that the icon maintains good contrast against various backgrounds in both light and dark modes.app/src/main/java/app/callgate/android/modules/db/Module.kt (1)
1-9: Clean Koin module implementation for the database layer.This module properly sets up singleton instances for both the database and the DAO, following the dependency injection pattern. The implementation is concise and adheres to Koin best practices.
app/src/main/java/app/callgate/android/modules/webhooks/Module.kt (1)
1-8: Good module implementation for the webhook service.The webhook module correctly uses the
singleOffunction which is a concise way to provide a singleton forWebHooksService. This approach aligns well with modern Koin usage patterns.app/src/main/res/drawable/ic_webhook.xml (1)
1-11: Well-structured vector drawable for webhook icon.The vector drawable uses appropriate dimensions and follows Android best practices. The white fill color will work well with automatic tinting based on theme attributes.
app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt (1)
1-8: Good orchestrator module implementation.The orchestrator module uses the same clean pattern as the webhooks module for providing a singleton service, which ensures consistency across the codebase.
app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookDTO.kt (1)
3-7: Well-structured DTO for webhook dataThis is a clean implementation of a data class that follows Kotlin best practices. The properties have appropriate nullability designations - allowing nullable IDs for new webhooks and requiring non-null URLs and event types.
Consider adding documentation to clarify:
- Whether the ID is client or server-generated
- Any specific format requirements for the URL field
build.gradle.kts (1)
5-6: Appropriate plugin additions for the new functionalityThe addition of KSP and Room plugins is consistent with implementing database functionality for webhook support. The KSP version (1.9.22-1.0.17) correctly matches the Kotlin version (1.9.22), and Room 2.6.1 is a recent stable version.
app/src/main/res/drawable/notif_webhook.xml (1)
1-9: Well-formatted vector drawable resourceThis vector drawable follows Android best practices:
- Standard 24dp dimensions aligning with Material Design guidelines
- White fill color allowing system tinting based on theme
- Properly structured vector path data
app/src/main/java/app/callgate/android/modules/calls/events/CallEvent.kt (1)
3-12: Well-structured data class for call state representation.The
CallEventdata class provides a clean abstraction for phone call states with appropriate properties. The enum type is well-designed with clear states (Ringing, Started, Ended) that align logically with typical call lifecycle events.app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEvent.kt (1)
5-14: Good design with proper serialization annotations.The
WebHookEventenum is well-structured and uses@SerializedNameannotations appropriately to ensure consistent JSON serialization. The enum values align nicely with theCallEvent.Typevalues, making it easy to map between them. The naming convention for JSON keys (using "call:" prefix) follows good domain separation practices.app/src/main/AndroidManifest.xml (1)
30-37: Ensure secure handling of the broadcast receiver.The broadcast receiver is correctly configured to listen for
PHONE_STATEactions. Since it's marked asexported="true", it can receive broadcasts from outside the application, which is necessary for system broadcasts but introduces security considerations.Make sure the
CallsReceiverimplementation validates incoming intents to ensure they're legitimate system broadcasts before processing them. This helps prevent potential misuse from malicious applications.app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt (1)
27-27: LGTM: Consistent naming conventionThe constant naming follows the established pattern in the companion object.
app/src/main/java/app/callgate/android/modules/server/routes/CallsRoutes.kt (2)
15-15: Class name change improves consistencyChanging from
CallRoutestoCallsRoutesimproves naming consistency, presumably to better reflect that it handles multiple calls.
39-39: Verify exception handling for this RuntimeExceptionChanged from responding with
HttpStatusCode.InternalServerErrorto throwing aRuntimeException. Ensure there's appropriate exception handling middleware in place to catch this exception and translate it to a proper HTTP response. Without proper handling, this could lead to unhandled exceptions or unexpected application behavior.#!/bin/bash # Search for exception handlers that might catch the RuntimeException echo "Searching for exception handlers in the application..." rg -A 10 "try\s*\{" --glob "*.kt" | rg -B 10 "catch\s*\(" echo "Searching for specific handlers for RuntimeException..." rg "catch\s*\(\s*RuntimeException" --glob "*.kt" echo "Searching for any global exception handling mechanism..." rg "application.install\(.*\)" --glob "*.kt" | rg -A 10 "StatusPages|ExceptionHandling"app/src/main/java/app/callgate/android/modules/settings/Module.kt (2)
5-6: LGTM: Import statements added for new dependenciesThe imports for
TemporaryStorageandWebhooksSettingsare correctly added.
21-30: Verify sharing of preferences between WebhooksSettings and TemporaryStorageBoth factories use the same preference key "webhooks". Confirm this is intentional and that there won't be key collisions between these two components accessing the same underlying storage. If they're meant to use different preferences, consider using distinct keys.
#!/bin/bash # Look at WebhooksSettings and TemporaryStorage implementations echo "Examining WebhooksSettings implementation:" fd "WebhooksSettings.kt" --type f | xargs cat echo "\nExamining TemporaryStorage implementation:" fd "TemporaryStorage.kt" --type f | xargs catapp/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt (2)
9-13: LGTM: Fragment implementation follows standard patternsThe WebhooksSettingsFragment correctly extends BasePreferenceFragment and loads preferences from the resource file.
1-8: Check that corresponding XML resource is properly definedMake sure the
R.xml.webhooks_preferencesresource file is properly defined with all the preferences referenced in this class (webhooks.retry_countandwebhooks.signing_key).#!/bin/bash # Check for the webhooks_preferences.xml file echo "Looking for webhooks_preferences.xml:" fd "webhooks_preferences.xml" --type f # Display the contents of the file if found webhooks_file=$(fd "webhooks_preferences.xml" --type f) if [ -n "$webhooks_file" ]; then echo "\nContents of webhooks_preferences.xml:" cat "$webhooks_file" else echo "\nwebhooks_preferences.xml not found." fiapp/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt (1)
54-54: Appropriate suppression annotation.The
@Suppress("UNCHECKED_CAST")annotation is correctly applied to suppress the compiler warnings about unchecked type casting. This is appropriate since the function performs type-specific retrievals from SharedPreferences and must cast the results.app/src/main/java/app/callgate/android/modules/server/Module.kt (1)
3-8: Good use of modern Koin syntax.The change from
single { ServerService() }tosingleOf(::ServerService)uses the more concise and modern Koin DSL syntax. This approach leverages constructor injection, suggesting that ServerService's constructor was updated to accept dependencies.app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt (3)
21-22: Appropriate deprecation suppression and handling for EXTRA_INCOMING_NUMBER.The code correctly uses
@Suppress("DEPRECATION")for the deprecatedEXTRA_INCOMING_NUMBERconstant. Make sure your app has the necessary permissions to access this information.Please ensure the app has the appropriate
READ_PHONE_STATEpermission declared in the AndroidManifest.xml file.
31-55: Well-structured call state handling.The code properly handles the three main phone states (ringing, active, idle) and creates appropriate event objects for each state. The approach to return early for unknown states is clean.
1-58: Verify CallsService integration.The implementation looks good overall. The receiver properly processes phone state changes and converts them to domain events. Make sure that
CallsService.processEvent()is implemented to handle these events correctly, particularly for webhooks integration.#!/bin/bash # Check if CallsService.processEvent is implemented rg -A 10 "fun\s+processEvent.*CallEvent" --type kotlinapp/src/main/java/app/callgate/android/modules/calls/CallsService.kt (3)
15-18: Good addition of relevant imports for webhook integration.The imports are correctly organized and clearly indicate the new webhook functionality being added to the CallsService.
22-25: Constructor properly updated to include WebHooksService dependency.Good implementation of dependency injection by adding the WebHooksService as a constructor parameter rather than creating it internally. This improves testability and follows the dependency inversion principle.
46-47: Improved code readability with direct variable assignment.Refactoring to directly assign
telephonyManager.callStateto a variable within the when expression improves code clarity.app/src/main/res/xml/webhooks_preferences.xml (1)
1-25: Well-structured preferences screen for webhook settings.The preferences layout follows a logical organization with appropriate icons, titles, and summaries. Good use of SimpleSummaryProvider for displaying current values.
app/src/main/java/app/callgate/android/modules/server/ServerService.kt (3)
6-8: Good improvement using dependency injection for settings.The constructor now properly accepts ServerSettings as a parameter instead of working with it directly, improving testability and following good dependency injection practices.
10-10: Device ID initialization is implemented well.Good approach to lazily initialize the device ID only when needed.
19-19: API simplification by removing unnecessary context parameter.Removing the context parameter from isActiveLiveData simplifies the API, which is good practice.
app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt (1)
10-18: Database configuration follows Room best practices.The @database annotation correctly defines the entity and version number, with space for future auto-migrations. Good organization and readability.
app/src/main/java/app/callgate/android/modules/server/WebService.kt (4)
17-18: Import statements updated for new webhook functionality.The import statements have been updated to use
CallsRoutesinstead ofCallRoutesand addedWebhooksRoutes, which aligns with the new webhook support being implemented.
57-57: Appropriate use of @Suppress annotation.The
@Suppress("DEPRECATION")annotation is correctly used to handle the deprecated API increateWifiLock. This is a good practice to acknowledge the use of deprecated APIs.
118-122: New webhook routes added to API.The routing configuration has been updated to include the new
/webhooksendpoint and the class name change fromCallRoutestoCallsRoutes. The webhook routes are properly registered using dependency injection withget().
142-142: Notification ID constant used for clarity.Using the constant
NotificationsService.NOTIFICATION_ID_LOCAL_SERVICEimproves code maintainability and ensures consistency in notification management.app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt (4)
1-6: Well-organized imports for the new webhook settings class.The imports are clean and include only what's necessary for the functionality.
7-9: Good practice injecting the storage dependency.Injecting the
KeyValueStoragedependency allows for better testing and flexibility in how settings are stored.
10-18: Well-designed settings properties with sensible defaults.The properties are well-designed with appropriate defaults:
internetRequireddefaults to true, which is a secure defaultretryCountdefaults to 1, a reasonable starting pointsigningKeygenerates a new key if not present, which is a good security practiceThe lazy generation of the signing key is a particularly good design choice.
20-24: Constants well defined in companion object.The constants are properly defined and named clearly in the companion object, making them easily accessible and maintainable.
app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt (5)
1-10: Appropriate imports for Room DAO implementation.The imports cover all necessary Room annotations and the domain entities required for webhook functionality.
12-19: Well-structured DAO interface with appropriate query methods.The DAO interface is properly annotated with
@Daoand includes well-designed query methods to select webhooks by event and source.
20-24: Proper upsert methods with conflict resolution.The upsert methods use the appropriate
OnConflictStrategy.REPLACEto handle conflicts, ensuring that database operations are robust.
26-30: Effective transaction method for replacing webhooks.The
replaceAlltransaction method efficiently handles the common use case of replacing all webhooks from a particular source, ensuring data consistency through the use of@Transaction.
32-36: Comprehensive delete operations.The delete methods provide granular control, allowing deletion of specific webhooks by ID and source, as well as bulk deletion by source.
app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSingingPlugin.kt (2)
49-56: Solid implementation of HMAC signature generation.The signature generation function is well-implemented using standard Java cryptography APIs.
58-60: Efficient byte array to hex string conversion.The extension function to convert a byte array to a hex string is concise and efficient.
app/src/main/java/app/callgate/android/modules/notifications/NotificationsService.kt (5)
18-21: Well-structured icon mapping implementationGood approach using a map to associate notification IDs with their corresponding drawable resources. This makes the code more maintainable as new notification types can be added by simply extending the map.
26-26: Notification channel description updateThe notification channel description has been updated from local server notifications to a more general "Call Gate Notifications", which better aligns with the expanded notification functionality that now includes webhooks.
36-36: Function signature update for notification ID supportThe makeNotification function now accepts an ID parameter, which allows for different notification types to be created from the same service.
40-40: Robust icon selection with fallbackGood implementation of icon selection with a fallback to the default icon if the provided ID doesn't match any entry in the map.
48-48: New notification ID constant for webhook workerThis addition supports the webhook functionality by providing a dedicated notification ID for the webhook worker process.
app/src/main/java/app/callgate/android/App.kt (3)
5-11: Updated imports for new modulesThe addition of imports for database, orchestrator, and webhook modules reflects the architectural changes made to support the webhook functionality.
26-32: Dependency injection modules updatedThe Koin configuration has been extended with new modules for database, webhooks, and orchestrator functionality, which aligns with the architectural changes.
35-35: Service initialization updated to use orchestratorThe application now uses the OrchestratorService to manage service lifecycle instead of directly starting the ServerService. This is a good architectural improvement that centralizes service management.
app/src/main/res/values/strings.xml (3)
14-20: New webhook notification stringsGood addition of string resources for webhook notifications and general app notifications, which supports the new webhook functionality.
22-119: Comprehensive string resources for webhook functionalityThe addition of a large number of string resources is well-organized and follows the existing naming conventions. These strings support various aspects of the webhook functionality including UI elements, notifications, and user prompts.
3-5: Retain information string resourcesThese strings appear to be kept in the file despite being marked as changes in the annotation. Make sure they're still referenced elsewhere in the codebase, otherwise they could be removed.
#!/bin/bash # Check if these strings are still being used in the codebase rg "R\.string\.app_version_build" --type java --type kotlin rg "R\.string\.information" --type java --type kotlinapp/src/main/java/app/callgate/android/ui/HomeFragment.kt (7)
17-18: Import for OrchestratorServiceAdded import for the new OrchestratorService while keeping the ServerService import, which indicates a separation of responsibilities.
26-28: Service dependency injection updateThe fragment now injects both the OrchestratorService for controlling service lifecycle and ServerService for observing the server state. This separation of concerns is a good architectural decision.
52-52: Server state observation updatedUpdated to use the dedicated serverSvc for observing the server's active state, which aligns with the new service architecture.
70-72: Start method updated for orchestratorThe start method now delegates to the OrchestratorService, passing the context and a flag to indicate this is not an auto-start. This change aligns with the new orchestration architecture.
74-76: Stop method updated for orchestratorSimilarly, the stop method has been updated to use the OrchestratorService, which centralizes the service lifecycle management.
80-80: Permission check update for API levelGood practice to conditionally include the ANSWER_PHONE_CALLS permission only for Android O and above using takeIf.
112-114: Simplified newInstance methodThe newInstance method has been simplified while maintaining the same functionality, which is a good refactoring.
app/src/main/res/xml/root_preferences.xml (4)
6-7: Good move to use string resources for internationalization.
Replacements of hard-coded strings with@stringreferences enhance maintainability and localization efforts.
9-13: Ensure the new preference strings exist.
Adding a newPreferencefor webhooks is consistent with the PR objectives. Just confirm that@string/retries_signing_etcand@string/webhooks_dotdotdotare defined and localized appropriately.
15-15: Localized “General” preference.
Using@string/generalis a straightforward improvement for maintainability.
18-18: Localized “Autostart” preference.
Switching to@string/autostartconsistently aligns with best practices.app/build.gradle.kts (6)
4-5: Added necessary plugins for Room.
Enablingkspandandroidx.roomaligns with the new database-related features in this PR.
20-23: Room schema directory configured.
Ensure the$projectDir/schemasfolder is created and included in version control if desired, so that schema snapshots are tracked.
56-57: Pinned versions for Room and WorkManager.
Defining explicitroomVersionandworkVersionfosters consistent builds.
79-81: Introduced new Ktor client libs.
These additions are essential for HTTP client functionality in the new webhook workflow.
86-91: Room runtime and KSP compiler dependencies.
All standard for a Room-based architecture. Ensure that the KSP tasks are running if you rely on generated code (e.g. DAOs).
92-93: Added WorkManager dependency.
This fully supports background tasks for webhooks, as seen in the new worker class.app/src/main/java/app/callgate/android/modules/db/Converters.kt (7)
1-2: File placement and package naming look proper.
No issues with the location or naming convention of the new converters file.
3-9: Imports check out.
Gson, JsonElement, and Room’sTypeConverterare appropriate for custom conversions.
11-13: Gson builder with date format.
Centralizing date format in theGsonBuilderis consistent and straightforward.
14-17: Stringifying a list.
Usinggson.toJson()is correct. Consider handling very large lists or complex data structures carefully, but this is fine for typical usage.
19-22: Parsing a JSON string to a list.
UsingArray<String>plus.toList()is a neat solution. Watch out for exceptions if the JSON content is invalid, but that’s a broader data validation concern.
34-42: Converting JsonElement to/from String.
Using Gson’s serialization works well here. No issues found.
44-49: Companion object for shared context.
Good approach for centralizing the date format and other static references.app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (7)
49-51: Injecting settings and storage.
This aligns with the new webhook architecture for persisting and retrieving payload data.
52-69: Return early when payload is null.
This logic to avoid useless network calls is good. Verification thatinputDataincludes valid data is important for overall reliability.
71-119: Graceful handling of success/failure/retry.
The approach of removingstorageKeyupon success or failure, but not retry, is correct. However, consider thoroughly verifying that repeated retries won’t cause indefinite loops when server continuously fails.
158-173: Foreground service notifications.
Good practice to inform the user about background operations. Implementation looks solid.
175-192: Ktor client with timeouts and a plugin for signing.
Instantiating and closing the client per work run is acceptable. Just confirm it doesn’t add excessive overhead if this worker is enqueued frequently.
194-199: Local sealed class.
Having a typed result flow is clear. Just be mindful thatResultname might cause confusion, as noted above.
200-241: Static method to enqueue the worker and attach constraints.
This is a clean, discoverable approach for consumers to start the worker. The constraints usage is aligned with typical WorkManager patterns.
app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt
Show resolved
Hide resolved
app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt
Show resolved
Hide resolved
app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt
Show resolved
Hide resolved
app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSingingPlugin.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt
Show resolved
Hide resolved
app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt
Show resolved
Hide resolved
| class WebHooksService( | ||
| private val webHooksDao: WebHooksDao, | ||
| private val localServerSettings: ServerSettings, | ||
| // private val gatewaySettings: GatewaySettings, | ||
| private val webhooksSettings: WebhooksSettings, | ||
| ) : KoinComponent { | ||
| // private val eventsReceiver by lazy { EventsReceiver() } | ||
|
|
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 documenting the purpose of this service and removing commented code.
The WebHooksService class contains commented-out code suggesting incomplete implementation or planned features. This makes it harder to understand the current implementation. Consider either implementing the commented code, removing it, or adding TODO comments with explanations.
class WebHooksService(
private val webHooksDao: WebHooksDao,
private val localServerSettings: ServerSettings,
-// private val gatewaySettings: GatewaySettings,
private val webhooksSettings: WebhooksSettings,
) : KoinComponent {
-// private val eventsReceiver by lazy { EventsReceiver() }
+ // Add class-level documentation explaining the role of this service and its lifecycle📝 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 WebHooksService( | |
| private val webHooksDao: WebHooksDao, | |
| private val localServerSettings: ServerSettings, | |
| // private val gatewaySettings: GatewaySettings, | |
| private val webhooksSettings: WebhooksSettings, | |
| ) : KoinComponent { | |
| // private val eventsReceiver by lazy { EventsReceiver() } | |
| class WebHooksService( | |
| private val webHooksDao: WebHooksDao, | |
| private val localServerSettings: ServerSettings, | |
| private val webhooksSettings: WebhooksSettings, | |
| ) : KoinComponent { | |
| // Add class-level documentation explaining the role of this service and its lifecycle |
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)
app/src/main/java/app/callgate/android/modules/calls/CallsService.kt (1)
78-93: Well-implemented webhook event processing with proper error handling.The processEvent method correctly maps call events to webhook events and includes proper error handling with try-catch. Good job logging errors rather than letting exceptions propagate, which is appropriate for this kind of side-effect operation.
🧹 Nitpick comments (6)
app/src/main/java/app/callgate/android/ui/settings/BasePreferenceFragment.kt (1)
6-6: Well implemented utility method for handling EditText focus!The new
configureEditTextmethod provides a convenient way to improve the usability of EditText fields in preference screens by auto-selecting all content when focused. This will make it easier for users to replace existing content.Consider adding a parameter to make the immediate selection optional:
- protected fun configureEditText(editText: EditText) { + protected fun configureEditText(editText: EditText, selectImmediately: Boolean = true) { editText.setSelectAllOnFocus(true) - editText.selectAll() + if (selectImmediately) { + editText.selectAll() + } }This would provide more flexibility when configuring EditText components in different scenarios.
Also applies to: 28-31
app/src/main/java/app/callgate/android/modules/calls/CallsService.kt (1)
90-91: Consider using Throwable vs Exception in catch block.You're using
Throwablein the catch block which will catch both Exceptions and Errors. While this provides maximum safety, catchingExceptionmight be more appropriate here as Errors typically represent serious problems that shouldn't be caught and handled.- } catch (th: Throwable) { - Log.e("CallsService", "Failed to emit webhook event", th) + } catch (e: Exception) { + Log.e("CallsService", "Failed to emit webhook event", e)app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt (1)
42-47: Configuration looks good, but consider adding validation.The configuration class provides reasonable defaults and a flexible secretKeyProvider.
Consider adding validation for the HMAC algorithm to ensure it's one of the supported algorithms (HmacSHA1, HmacSHA256, etc.) to fail fast with clear error messages rather than at runtime.
class PayloadSigningPluginConfig { var secretKeyProvider: () -> String? = { null } var signatureHeaderName: String = "X-Signature" var timestampHeaderName: String = "X-Timestamp" var hmacAlgorithm: String = "HmacSHA256" + + fun validate() { + val supportedAlgorithms = listOf("HmacSHA1", "HmacSHA256", "HmacSHA512") + require(hmacAlgorithm in supportedAlgorithms) { + "Unsupported HMAC algorithm: $hmacAlgorithm. Supported algorithms: $supportedAlgorithms" + } + } }app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (3)
47-116: Decide on the status of the commented-out logging code.There are multiple blocks of commented-out logging code in lines 47–48, 59–68, 73–82, 90–99, and 107–116. If these logs are no longer needed, you may remove them. Otherwise, consider uncommenting and properly configuring the Logging/LogsService usage to maintain diagnostic visibility.
121-156: Refine return handling insendDatato improve clarity.Line 141 contains a mere expression
SendResult.Successwithout actually returning, whereas line 155 performs the actualreturn SendResult.Success. This can be confusing. Consider removing the no-op line 141 or converting it into a properreturn SendResult.Successstatement to make the flow clearer.--- a/SendWebhookWorker.kt +++ b/SendWebhookWorker.kt @@ -140,7 +140,7 @@ if (response.status.value !in 200..299) { return SendResult.Retry("Status code: ${response.status.value}") } - SendResult.Success + return SendResult.Success } catch (e: IllegalArgumentException) { e.printStackTrace() return SendResult.Failure(e.message ?: e.toString())
207-235: Ensure large payloads are handled and stored safely.Storing potentially large webhook data (
gson.toJson(data)) inTemporaryStoragemay lead to performance or memory concerns. If there's a chance of large payloads, consider validating the size before storing or using a more robust approach (e.g., streaming or chunking).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsService.kt(3 hunks)app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt(1 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt(1 hunks)app/src/main/java/app/callgate/android/ui/settings/BasePreferenceFragment.kt(2 hunks)app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt(1 hunks)app/src/main/res/xml/webhooks_preferences.xml(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
- app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt
- app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt
- app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt
- app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt
- app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt
- app/src/main/res/xml/webhooks_preferences.xml
- app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt
- app/src/main/java/app/callgate/android/modules/webhooks/Module.kt
- app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (3)
app/src/main/java/app/callgate/android/extensions/GsonBuilder.kt (1)
configure(7-9)app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt (1)
get(13-15)app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt (1)
get(32-46)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Build / build-apk
🔇 Additional comments (5)
app/src/main/java/app/callgate/android/modules/calls/CallsService.kt (2)
23-26: Excellent dependency injection implementation.Adding WebHooksService as a constructor parameter follows good dependency injection practices and makes the class more testable.
41-48: Clean refactoring and appropriate use of suppression.The refactoring makes the code more concise by directly using the callState variable in the when expression. The
@Suppress("DEPRECATION")annotation is correctly used to acknowledge the use of deprecated APIs.app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt (2)
58-60: Hex conversion looks good.The ByteArray.toHexString extension function is implemented correctly and efficiently.
1-9: Imports look appropriate.The imports are appropriate for the functionality provided by this class. The use of javax.crypto classes for HMAC operations and Ktor client plugin APIs is correct.
app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (1)
194-198:Details
✅ Verification successful
Confirm Kotlin version support for data objects.
This sealed class declares a data object (
data object Success), which requires Kotlin 1.8 or higher. Verify that your project settings align with this requirement to avoid compilation errors.
🏁 Script executed:
#!/bin/bash # Description: Check Kotlin Gradle plugin version from build.gradle files. rg -A 3 "kotlin(\"jvm\""Length of output: 94
Verify Kotlin Gradle Plugin Version (≥1.8) for Data Object Support
The use of a
data objectinSendWebhookWorker.ktrequires that your project’s Kotlin configuration is set to version 1.8 or higher. Our initial attempt to check the build configuration produced a regex error. Please run the shell script below to inspect your Gradle files for the Kotlin plugin declaration and verify the version:
- Action Items:
- Run the above script from the repository root.
- Confirm that the output indicates a Kotlin version of 1.8 or higher.
- If the version is lower, update your project’s Kotlin Gradle plugin accordingly to ensure compatibility with
data object.
🏁 Script executed:
#!/bin/bash # Searching for the Kotlin plugin declaration using fixed-string search to avoid regex errors. rg --fixed-strings 'kotlin("jvm")' -A 3 .Length of output: 165
Action: Verify Kotlin Version (≥1.8) for Data Object Support
The use of a
data objectin the sealed class requires that your project is using Kotlin 1.8 or newer. Our initial automated checks were inconclusive. Please perform the following manual verification:
- Verify Gradle Configuration:
Look in yourbuild.gradleorbuild.gradle.ktsfiles for the Kotlin plugin declaration (e.g., lines containingorg.jetbrains.kotlinor a Kotlin version property such askotlin_version). Ensure the declared version is 1.8 or higher.For additional assistance, you can run this script from the repository root:
This will help you locate the necessary information. Once verified, confirm that the settings are aligned with the requirements for
data object.
🏁 Script executed:
#!/bin/bash # Search for Kotlin version indicators in Gradle build files. echo "Searching for Kotlin plugin declarations and version info:" rg -n 'org.jetbrains.kotlin' . rg -n 'kotlin_version' .Length of output: 686
Kotlin Version Verified for Data Object Support
Our Gradle files confirm that the Kotlin plugin is set to version 1.9.22 (see
./build.gradle.kts:4), which more than satisfies the requirement for usingdata object(Kotlin 1.8 or higher). No changes are needed here.
| fun generateSignature(algorithm: String, secretKey: String, payload: String): String { | ||
| val mac = Mac.getInstance(algorithm) | ||
| val secretKeySpec = SecretKeySpec(secretKey.toByteArray(), algorithm) | ||
| mac.init(secretKeySpec) | ||
| val hash = mac.doFinal(payload.toByteArray()) | ||
|
|
||
| return hash.toHexString() | ||
| } |
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
Improve error handling in signature generation.
The generateSignature function works correctly but lacks proper error handling for cryptographic operations.
Add try-catch blocks to handle potential exceptions and specify explicit character encoding:
fun generateSignature(algorithm: String, secretKey: String, payload: String): String {
- val mac = Mac.getInstance(algorithm)
- val secretKeySpec = SecretKeySpec(secretKey.toByteArray(), algorithm)
- mac.init(secretKeySpec)
- val hash = mac.doFinal(payload.toByteArray())
-
- return hash.toHexString()
+ try {
+ val mac = Mac.getInstance(algorithm)
+ val secretKeySpec = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8), algorithm)
+ mac.init(secretKeySpec)
+ val hash = mac.doFinal(payload.toByteArray(Charsets.UTF_8))
+
+ return hash.toHexString()
+ } catch (e: Exception) {
+ // Log the error, but don't expose details that might aid attackers
+ Log.e("PayloadSigning", "Error generating signature", e)
+ throw RuntimeException("Failed to generate signature")
+ }
}📝 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.
| fun generateSignature(algorithm: String, secretKey: String, payload: String): String { | |
| val mac = Mac.getInstance(algorithm) | |
| val secretKeySpec = SecretKeySpec(secretKey.toByteArray(), algorithm) | |
| mac.init(secretKeySpec) | |
| val hash = mac.doFinal(payload.toByteArray()) | |
| return hash.toHexString() | |
| } | |
| fun generateSignature(algorithm: String, secretKey: String, payload: String): String { | |
| try { | |
| val mac = Mac.getInstance(algorithm) | |
| val secretKeySpec = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8), algorithm) | |
| mac.init(secretKeySpec) | |
| val hash = mac.doFinal(payload.toByteArray(Charsets.UTF_8)) | |
| return hash.toHexString() | |
| } catch (e: Exception) { | |
| // Log the error, but don't expose details that might aid attackers | |
| Log.e("PayloadSigning", "Error generating signature", e) | |
| throw RuntimeException("Failed to generate signature") | |
| } | |
| } |
app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt
Show resolved
Hide resolved
🤖 Pull request artifacts
|
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: 0
♻️ Duplicate comments (2)
app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt (2)
26-26: Add a separator to avoid potential signature collisions.Direct string concatenation of
content.textand the timestamp may cause collisions (e.g., ifcontent.textends with digits). Consider adding a separator:- val message = content.text + timestamp + val message = "${content.text}:${timestamp}"
49-56: Add try-catch blocks for cryptographic operations.The
generateSignaturefunction should handle potential exceptions likeNoSuchAlgorithmExceptionorInvalidKeyException. For instance:-fun generateSignature(algorithm: String, secretKey: String, payload: String): String { - val mac = Mac.getInstance(algorithm) - val secretKeySpec = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8), algorithm) - mac.init(secretKeySpec) - val hash = mac.doFinal(payload.toByteArray(Charsets.UTF_8)) - return hash.toHexString() +fun generateSignature(algorithm: String, secretKey: String, payload: String): String { + return try { + val mac = Mac.getInstance(algorithm) + val secretKeySpec = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8), algorithm) + mac.init(secretKeySpec) + val hash = mac.doFinal(payload.toByteArray(Charsets.UTF_8)) + hash.toHexString() + } catch (ex: Exception) { + // Log or rethrow the exception as appropriate + throw IllegalStateException("Failed to generate signature.", ex) + } +}
🧹 Nitpick comments (3)
app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (3)
46-48: Remove or reintroduce unused log statements.Large blocks of commented out logging code can lead to clutter and confusion. If you no longer need these logs, remove them; otherwise, reintroduce them in an organized manner, ensuring they provide meaningful diagnostic information.
Also applies to: 58-68, 73-81, 90-98, 107-115
121-154: Distinguish between 4xx and 5xx status codes.Currently, all non-2xx responses trigger a retry. For 4xx client errors (e.g., malformed request), continuously retrying might be futile. Consider failing immediately on 4xx, while continuing to retry on 5xx server errors or timeouts.
173-190: Consider avoiding client creation on each call (optional).Re-initializing and closing the
HttpClienton every method invocation might be inefficient. If the worker is invoked frequently, consider a shared or lazily initialized client instance to reduce overhead.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (3)
app/src/main/java/app/callgate/android/extensions/GsonBuilder.kt (1)
configure(7-9)app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt (1)
get(13-15)app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt (1)
get(32-46)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Build / build-apk
🔇 Additional comments (4)
app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (4)
1-42: No major issues found.
43-45: Looks good!The class declaration and inheritance structure are clear and appropriate for a custom Worker implementation.
198-239: Validate the uniqueness of data IDs.In the
startmethod,data.idis used as the key inTemporaryStorage. Ifdata.idcollides, you could risk overwriting or losing payloads. Confirm that IDs are consistently unique.
52-119:Details
❓ Verification inconclusive
Confirm concurrency safety with ephemeral storage.
If multiple workers share the same storage key, there is a potential race condition when retrieving or removing a payload. Please verify that use cases won't trigger simultaneous workers on the same key, or ensure
TemporaryStorageis concurrency-safe.
🏁 Script executed:
#!/bin/bash # Searching for concurrency handling of TemporaryStorage throughout the codebase. rg 'TemporaryStorage' -A 10Length of output: 6858
Action required: Verify concurrency safety for TemporaryStorage usage.
The use ofTemporaryStorageinSendWebhookWorker.ktmay lead to race conditions if multiple workers access or remove the same key concurrently. Please confirm that the underlyingKeyValueStorage(or usage context) ensures thread-safe operations. If concurrent access is possible, consider adding appropriate synchronization mechanisms.
- File:
app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt– review concurrent retrieval/removal on the same key.- File:
app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt– verify ifKeyValueStorageprovides the necessary concurrency guarantees.
e938ccd to
f1c059d
Compare
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: 3
♻️ Duplicate comments (9)
app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt (3)
24-26: Add error handling for potential exceptions in GET route.
This repeats a suggestion made in a previous review. As recommended earlier, consider wrapping service calls in a try-catch block to handle possible exceptions and respond with an appropriate error code.
27-32: Add error handling for potential exceptions in POST route.
This repeats a suggestion made in a previous review. Thereplaceoperation can fail due to service- or I/O-related issues, so consider catching exceptions and returning an error response.
33-37: Add error handling for potential exceptions in DELETE route.
This repeats a suggestion made in a previous review. If an error occurs inwebHooksService.delete(EntitySource.Local, id), users won't receive an explanatory error message. Wrap the service call in a try-catch block and return error responses accordingly.app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt (2)
49-56: 🛠️ Refactor suggestionImprove error handling in signature generation.
The generateSignature function works correctly but lacks proper error handling for cryptographic operations.
fun generateSignature(algorithm: String, secretKey: String, payload: String): String { - val mac = Mac.getInstance(algorithm) - val secretKeySpec = SecretKeySpec(secretKey.toByteArray(charset = Charsets.UTF_8), algorithm) - mac.init(secretKeySpec) - val hash = mac.doFinal(payload.toByteArray(charset = Charsets.UTF_8)) - - return hash.toHexString() + try { + val mac = Mac.getInstance(algorithm) + val secretKeySpec = SecretKeySpec(secretKey.toByteArray(charset = Charsets.UTF_8), algorithm) + mac.init(secretKeySpec) + val hash = mac.doFinal(payload.toByteArray(charset = Charsets.UTF_8)) + + return hash.toHexString() + } catch (e: Exception) { + // Log the error, but don't expose details that might aid attackers + android.util.Log.e("PayloadSigning", "Error generating signature", e) + throw RuntimeException("Failed to generate signature") + } }
25-26: 🛠️ Refactor suggestionAvoid signature collisions by using a separator in the message construction.
The current message construction directly concatenates content and timestamp without a separator. This could potentially lead to signature collisions if the content text ends with digits that might be confused with the timestamp.
- val message = content.text + timestamp + val message = "${content.text}:${timestamp}"app/src/main/java/app/callgate/android/modules/db/Converters.kt (1)
24-32: Fix thread-safety issue in date conversions.SimpleDateFormat is not thread-safe, and Room converters can be called from multiple threads simultaneously. This can lead to unexpected behavior or crashes.
app/src/main/java/app/callgate/android/modules/server/ServerService.kt (1)
21-31: Device ID generation method could be improved.The current device ID generation has potential issues:
- hashCode() doesn't guarantee uniqueness across devices
- No error handling for getPackageInfo failures
- Some devices might return empty or unpredictable values for MANUFACTURER/PRODUCT
private fun getDeviceId(context: Context): String { - val firstInstallTime = context.packageManager.getPackageInfo( - context.packageName, - 0 - ).firstInstallTime - val deviceName = "${Build.MANUFACTURER}/${Build.PRODUCT}" - - return deviceName.hashCode().toULong() - .toString(16).padStart(16, '0') + firstInstallTime.toULong() - .toString(16).padStart(16, '0') + try { + val firstInstallTime = context.packageManager.getPackageInfo( + context.packageName, + 0 + ).firstInstallTime + + // Use more reliable device identifiers with fallbacks + val deviceInfo = (Build.MANUFACTURER.takeIf { it.isNotBlank() } ?: "unknown") + "/" + + (Build.PRODUCT.takeIf { it.isNotBlank() } ?: Build.MODEL ?: "unknown") + + // Use UUID with deviceInfo as namespace for better uniqueness + val deviceComponent = UUID.nameUUIDFromBytes(deviceInfo.toByteArray()) + .toString().replace("-", "").substring(0, 16) + + return deviceComponent + firstInstallTime.toULong() + .toString(16).padStart(16, '0') + } catch (e: Exception) { + // Fallback to a random UUID if anything fails + return UUID.randomUUID().toString().replace("-", "") + } }app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt (1)
17-17: Protect against null intent action.The current check might cause a NullPointerException if the intent action is null. Consider using a null-safe approach.
- if (TelephonyManager.ACTION_PHONE_STATE_CHANGED != intent.action) return + if (TelephonyManager.ACTION_PHONE_STATE_CHANGED != intent.action) returnapp/src/main/java/app/callgate/android/modules/calls/CallsService.kt (1)
78-93: Error handling implemented for webhook event emission.The implementation properly catches potential errors during webhook event emission and logs them, which addresses the previous review comment.
However, consider:
- Adding KDoc documentation for this method explaining its purpose
- Using more specific exception types if possible, rather than catch-all Throwable
+/** + * Processes call events by mapping them to webhook events and emitting them via WebHooksService. + * + * @param event The call event to process + */ fun processEvent(event: CallEvent) { val webhookEvent = when (event.type) { CallEvent.Type.Ringing -> WebHookEvent.CallRinging CallEvent.Type.Started -> WebHookEvent.CallStarted CallEvent.Type.Ended -> WebHookEvent.CallEnded } try { webHooksService.emit( webhookEvent, CallEventPayload(event.phoneNumber) ) - } catch (th: Throwable) { + } catch (e: Exception) { - Log.e("CallsService", "Failed to emit webhook event", th) + Log.e("CallsService", "Failed to emit webhook event", e) } }
🧹 Nitpick comments (29)
app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt (1)
28-29: Validate request data in the POST route.
Ensure thatWebHookDTOis valid before passing it to the service layer. For example, if the object is missing required fields, you could respond with a400 Bad Requestinstead of letting an exception propagate from the service layer.app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt (1)
58-60: Consider a more efficient hex string conversion.The current implementation uses string formatting for each byte, which creates many temporary string objects. For improved performance with large payloads, consider a more efficient implementation.
private fun ByteArray.toHexString(): String { - return joinToString("") { "%02x".format(it) } + val hexChars = "0123456789abcdef" + val result = StringBuilder(size * 2) + forEach { byte -> + val i = byte.toInt() + result.append(hexChars[i shr 4 and 0x0f]) + result.append(hexChars[i and 0x0f]) + } + return result.toString() }app/src/main/java/app/callgate/android/modules/db/Converters.kt (3)
11-12: Consider using a single source of truth for date format pattern.You're defining the date format pattern both in the GSON builder and in the companion object. This duplication can lead to inconsistencies if one is changed but not the other.
class Converters { - private val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create() + private val gson = GsonBuilder().create()Then update the
jsonToStringandstringToJsonmethods to use the date format from the companion object for any date serialization/deserialization.
14-22: Add error handling for JSON parsing.The JSON parsing operations could throw exceptions if the input is malformed. Consider adding try-catch blocks to handle these exceptions gracefully.
@TypeConverter fun listFromString(value: String?): List<String>? { - return value?.let { gson.fromJson(it, Array<String>::class.java).toList() } + return value?.let { + try { + gson.fromJson(it, Array<String>::class.java).toList() + } catch (e: Exception) { + null + } + } }
34-42: Add error handling for JSON parsing in JsonElement conversions.Similar to the list conversions, add try-catch blocks to handle potential exceptions during JSON parsing.
@TypeConverter fun stringToJson(value: String?): JsonElement? { - return value?.let { gson.fromJson(it, JsonElement::class.java) } + return value?.let { + try { + gson.fromJson(it, JsonElement::class.java) + } catch (e: Exception) { + null + } + } }app/src/main/res/values/strings.xml (11)
14-24: New Webhook and API String Resources Added
New string resources such assending_webhook,call_gate_notifications,address_is,api_url, andapi_url_private_token_credentials_etchave been added. These support the new webhook functionality. Ensure that these texts adhere to the app’s UI/UX guidelines and that placeholders (e.g.,%1$s) are correctly formatted across the app.
25-32: Battery Optimization and Button Labels Update
The new strings for battery optimization (battery_optimization,battery_optimization_already_disabled,battery_optimization_is_not_supported_on_this_device) and UI labels (e.g.,btn_cancel,btn_continue,by_code) are clear and descriptive. For the long instructional text on line 32, confirm that the newline (\n) and overall formatting render as expected in the UI.
33-47: Additional Server and Error Message Strings
A broad set of strings—including those for cloud server display (cloud_server,cloud_server_dotdotdot), user feedback messages (e.g.,copied_to_clipboard), and error prompts (e.g.,failed_to_change_password,failed_to_get_login_code,failed_to_register_device)—have been added. Ensure that these messages are consistent with existing messaging styles and that any placeholders are used correctly throughout the codebase.
48-58: Network Connectivity and Local Server Labels
The new resources covering network statuses (e.g.,internet_connection_available,internet_connection_unavailable) and local server details (e.g.,local_address,local_server_dotdotdot,local_sms_gateway_notifications) are well integrated. Please verify that format specifiers and dynamic content (such as%1$sor%2$d) are consistent with their usage in the application logic.
59-66: Login and Log Message String Updates
The additions for login codes (login_code,login_code_expires) and log-related texts (logs,maximum,messages,messages_count,messages_header,minimum) appear comprehensive. Double-check that the placeholders and text length are optimized for varying screen sizes and locales.
67-76: Settings, Status, and Password Policy Strings
New strings addressing additional settings, status indicators, and password requirements (e.g.,more_settings,notification_title,online_status_at_the_cost_of_battery_life,password_changed_successfully,password_must_be_at_least_14_characters,period) have been added. Ensure that these texts maintain a consistent tone and are easily understandable to end users across all supported languages.
77-84: Ping, Registration, and Credential Prompt Strings
The string resources for ping functionality and credentials (e.g.,ping,ping_service_is_active,please_enter_one_time_code_displayed_on_already_registered_device,port_credentials_etc,private_token,public_address,require_internet_connection,retries_signing_etc) have been introduced. Verify that error messages and dynamic placeholders (%1$s) are in sync with the corresponding code that formats these messages.
85-93: Server Address and Retry Settings Strings
New entries for retry counts, server address details, and configuration instructions (retry_count,send_messages_notification,server_address,set_maximum_value_to_activate,settings_address_is_sms_capcom_me,settings_local_address_is,settings_local_address_not_found,settings_local_server,settings_offline) have been added. Please ensure these are intuitive for users and correctly handle any dynamic values.
94-101: Authentication and SMS Gateway Resource Updates
Strings related to authentication (sign_in,sign_up,signing_key) and SMS Gateway configuration (sms_gateway,sms_gateway_is_running_on_port) are now present. Confirm that any hard-coded backend references (e.g.,api.sms-gate.appin line 89) accurately reflect the current server endpoints and that they are maintained according to backend changes.
102-107: Notification and Tab Label Texts
New resources for notifications and tab labels (success_long_press_to_copy,system,tab_text_home,tab_text_messages,tab_text_settings) are clear and align with the current design language. Check that the ellipsis usage (e.g., in...) and capitalization are consistent across the application.
108-116: Webhook Connection and Device Addition Guidance
The final block of string additions, including detailed instructions for webhook requests (the_webhook_request_will_wait_for_an_internet_connection) and device addition flows (e.g.,to_add_a_device_to_an_existing_account_please_fill_in_the_credentials_below,to_apply_the_changes_restart_the_app_using_the_button_below,use_empty_to_disable,use_this_code_to_sign_in_on_another_device,view,webhooks,webhooks_dotdotdot,server_dotdotdot), provides essential guidance for users. Given the extended text (especially multi-line instructions on line 109), verify that the formatting and line breaks are rendered properly in the UI to ensure readability.app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt (1)
32-33: Parameter order is reversed from the SQL placeholders.Although named parameters in the query ensure correctness, consider matching the parameter order for clarity:
@Query("DELETE FROM webHook WHERE id = :id AND source = :source") fun delete(id: String, source: EntitySource)app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (2)
43-48: Commented-out logs reference.If these logs are still relevant to debugging, consider uncommenting or removing them altogether to avoid confusion.
121-154: Distinguish 4xx and 5xx errors if needed.Currently, all non-200-level responses trigger a retry. This is acceptable for transient errors but might cause repeated retries for permanent 4xx errors. Consider a stricter approach if 4xx indicates a permanent failure.
app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt (2)
16-42: Clean handling of service startup with proper error handling.The start method correctly:
- Checks autostart conditions
- Manages service startup order
- Properly handles Android S+ foreground service restrictions
The commented-out logging code (lines 33-37) should either be removed or implemented.
-// logsSvc.insert( -// LogEntry.Priority.WARN, -// MODULE_NAME, -// "Can't start foreground services while the app is running in the background" -// )
1-58: Missing module name constant.The error logging uses hardcoded strings for the tag "OrchestratorService". Consider defining a MODULE_NAME constant.
package app.callgate.android.modules.orchestrator import android.app.ForegroundServiceStartNotAllowedException import android.content.Context import android.os.Build import android.util.Log import app.callgate.android.modules.server.ServerService import app.callgate.android.modules.settings.GeneralSettings import app.callgate.android.modules.webhooks.WebHooksService +private const val MODULE_NAME = "OrchestratorService" + class OrchestratorService( private val settings: GeneralSettings, private val serverSvc: ServerService, private val webHooksSvc: WebHooksService, ) { // ... // Then replace all occurrences of "OrchestratorService" with MODULE_NAME in Log.e callsapp/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt (1)
24-29: Remove or implement commented debug code.There's commented debug code for logging intent extras. Either remove it completely or implement it behind a debug flag if it's useful for troubleshooting.
-// Log.d( -// "CallsReceiver", -// "Extras: ${ -// intent.extras?.keySet()?.joinToString { "${it}: ${intent.extras?.get(it)}" } -// }" -// )app/src/main/java/app/callgate/android/modules/calls/CallsService.kt (1)
41-41: Appropriate use of @Suppress("DEPRECATION") annotation.The annotations clearly acknowledge the use of deprecated APIs in the getCall() and endCall() methods. Consider adding a comment explaining why these deprecated APIs are still being used and if there's a plan to migrate to newer alternatives.
Also applies to: 74-74
app/src/main/java/app/callgate/android/ui/HomeFragment.kt (2)
26-27: Good architectural refactoring with OrchestratorService.The code now follows better separation of concerns by using OrchestratorService for controlling application state and ServerService for observing the server state.
Consider using consistent naming conventions - the class is named ServerService but the variable is abbreviated as serverSvc.
70-72: Consider documenting boolean parameter meaning.The false parameter passed to orchestratorSvc.start() lacks context about what it represents, making the code harder to understand.
private fun start() { - orchestratorSvc.start(requireContext(), false) + // false parameter indicates manual start (not triggered by boot) + orchestratorSvc.start(requireContext(), isBootTriggered = false) }README.md (4)
29-30: Minor Language Suggestion.
Consider rephrasing “Change random password to something secure, if necessary” to “Change the random password to something secure, if necessary” for improved clarity.
97-100: Webhook Requirements Section.
The requirements are concisely listed. Consider specifying that the SSL certificate should be both valid and properly installed on the receiver device for additional clarity.🧰 Tools
🪛 LanguageTool
[duplication] ~98-~98: Possible typo: you repeated a word.
Context: ...uirements:** - Valid SSL certificate on receiver - Receiver accessible from device ### SMSGate Co...(ENGLISH_WORD_REPEAT_RULE)
73-78: Markdown Formatting Suggestion for Tables.
Ensure that tables—such as those in the "Events" section—are surrounded by blank lines as recommended by markdownlint for improved readability and compliance with markdown standards.🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
73-73: Tables should be surrounded by blank lines
null(MD058, blanks-around-tables)
98-98: Nitpick: Reword Requirements.
Consider revising “Valid SSL certificate on receiver” to “Valid SSL certificate installed on the receiver device” to enhance clarity and eliminate ambiguity.🧰 Tools
🪛 LanguageTool
[duplication] ~98-~98: Possible typo: you repeated a word.
Context: ...uirements:** - Valid SSL certificate on receiver - Receiver accessible from device ### SMSGate Co...(ENGLISH_WORD_REPEAT_RULE)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (52)
README.md(1 hunks)app/build.gradle.kts(4 hunks)app/schemas/app.callgate.android.modules.db.AppDatabase/1.json(1 hunks)app/src/main/AndroidManifest.xml(1 hunks)app/src/main/java/app/callgate/android/App.kt(2 hunks)app/src/main/java/app/callgate/android/domain/EntitySource.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsService.kt(3 hunks)app/src/main/java/app/callgate/android/modules/calls/events/CallEvent.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/Converters.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/notifications/NotificationsService.kt(2 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/ServerService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt(2 hunks)app/src/main/java/app/callgate/android/modules/server/WebService.kt(6 hunks)app/src/main/java/app/callgate/android/modules/server/routes/CallsRoutes.kt(2 hunks)app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt(1 hunks)app/src/main/java/app/callgate/android/modules/settings/Module.kt(2 hunks)app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHook.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookDTO.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEvent.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEventDTO.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt(1 hunks)app/src/main/java/app/callgate/android/ui/HomeFragment.kt(5 hunks)app/src/main/java/app/callgate/android/ui/settings/BasePreferenceFragment.kt(2 hunks)app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt(1 hunks)app/src/main/res/drawable-notnight/ic_no_internet.xml(1 hunks)app/src/main/res/drawable-notnight/ic_retry.xml(1 hunks)app/src/main/res/drawable-notnight/ic_signing_key.xml(1 hunks)app/src/main/res/drawable-notnight/ic_webhook.xml(1 hunks)app/src/main/res/drawable/ic_no_internet.xml(1 hunks)app/src/main/res/drawable/ic_retry.xml(1 hunks)app/src/main/res/drawable/ic_signing_key.xml(1 hunks)app/src/main/res/drawable/ic_webhook.xml(1 hunks)app/src/main/res/drawable/notif_server.xml(1 hunks)app/src/main/res/drawable/notif_webhook.xml(1 hunks)app/src/main/res/values/strings.xml(2 hunks)app/src/main/res/xml/root_preferences.xml(1 hunks)app/src/main/res/xml/webhooks_preferences.xml(1 hunks)build.gradle.kts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (39)
- app/src/main/res/drawable-notnight/ic_no_internet.xml
- app/src/main/java/app/callgate/android/domain/EntitySource.kt
- app/src/main/res/drawable/ic_no_internet.xml
- app/src/main/res/drawable-notnight/ic_retry.xml
- app/src/main/res/drawable/notif_webhook.xml
- app/src/main/res/drawable/ic_retry.xml
- app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt
- app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt
- app/src/main/java/app/callgate/android/ui/settings/BasePreferenceFragment.kt
- app/src/main/java/app/callgate/android/modules/db/Module.kt
- app/src/main/java/app/callgate/android/modules/calls/events/CallEvent.kt
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEvent.kt
- app/src/main/res/drawable/ic_webhook.xml
- app/src/main/res/drawable/notif_server.xml
- app/src/main/res/drawable-notnight/ic_webhook.xml
- app/src/main/java/app/callgate/android/modules/webhooks/Module.kt
- app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt
- app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt
- app/src/main/java/app/callgate/android/modules/server/routes/CallsRoutes.kt
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookDTO.kt
- app/src/main/java/app/callgate/android/modules/settings/Module.kt
- app/src/main/res/drawable-notnight/ic_signing_key.xml
- app/src/main/res/drawable/ic_signing_key.xml
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEventDTO.kt
- build.gradle.kts
- app/src/main/AndroidManifest.xml
- app/src/main/java/app/callgate/android/modules/webhooks/db/WebHook.kt
- app/schemas/app.callgate.android.modules.db.AppDatabase/1.json
- app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt
- app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt
- app/src/main/res/xml/webhooks_preferences.xml
- app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt
- app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt
- app/src/main/java/app/callgate/android/modules/notifications/NotificationsService.kt
- app/src/main/java/app/callgate/android/modules/server/Module.kt
- app/build.gradle.kts
- app/src/main/java/app/callgate/android/modules/server/WebService.kt
- app/src/main/res/xml/root_preferences.xml
- app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt
🧰 Additional context used
🧬 Code Graph Analysis (2)
app/src/main/java/app/callgate/android/App.kt (2)
app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt (1)
get(32-46)app/src/main/java/app/callgate/android/modules/settings/KeyValueStorage.kt (2)
get(8-8)get(12-14)
app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt (1)
app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt (1)
delete(82-84)
🪛 LanguageTool
README.md
[uncategorized] ~25-~25: You might be missing the article “the” here.
Context: ...e device ### Installation 1. [Download latest APK](https://github.com/call-gate-app/a...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[duplication] ~98-~98: Possible typo: you repeated a word.
Context: ...uirements:** - Valid SSL certificate on receiver - Receiver accessible from device ### SMSGate Co...
(ENGLISH_WORD_REPEAT_RULE)
🪛 markdownlint-cli2 (0.17.2)
README.md
73-73: Tables should be surrounded by blank lines
null
(MD058, blanks-around-tables)
🔇 Additional comments (52)
app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt (2)
42-47: Configuration class is well-structured with appropriate defaults.The PayloadSigningPluginConfig class provides a good set of configurable parameters with sensible default values. This makes the plugin flexible while remaining easy to use with minimal configuration.
10-40: Well-structured plugin implementation follows Ktor's patterns.The PayloadSigningPlugin implementation correctly follows Ktor's client plugin patterns and provides a clean way to add HMAC signatures to outgoing requests. The header names are configurable, making this implementation flexible for different API requirements.
app/src/main/res/values/strings.xml (2)
3-5: Inconsistent Removal of String Resources
The AI summary indicates that the stringsapp_version_buildandinformationshould have been removed. However, they are still present on lines 3 and 5. Please verify whether these resources are now required or if they should be removed to match the intended changes.Likely an incorrect or invalid review comment.
117-118: General UI Text Resources
The added generic strings (general,autostart) are concise and straightforward. Ensure they are correctly integrated with the corresponding features within the app.app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt (9)
1-2: Overall file structure looks good.No issues noted in the package declaration.
3-11: Imports appear consistent with Room usage.All required import statements are present, and no redundant imports are visible here.
12-13: Good use of@Dao.Defining a dedicated DAO supports clearer separation of database operations, improving maintainability.
14-15: Query syntax check.The query correctly references the
eventfield in thewebHooktable. Ensure there's a corresponding field in theWebHookentity mapped asevent.
17-18: Consistent naming withsource.The query uses the
sourcefield. Make sure that theWebHookentity properly defines this column as well.
20-21: Upsert pattern on single entity.Using
REPLACEfor single-entity upsert is fine. Confirm that you don't need the new row ID for subsequent operations.
23-24: Batch upsert logic.Upserting multiple items is consistent with
OnConflictStrategy.REPLACE. Just be aware it may overwrite existing rows with matching primary keys.
26-30: Transaction usage is correct.Wrapping the delete-then-insert cycle with a
@Transactionensures atomicity.
35-36: Source-specific batch delete.Method name and annotations are self-explanatory and consistent.
app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (7)
49-51: Dependency injection approach.Injecting
WebhooksSettingsandTemporaryStorageis consistent and promotes testability.
52-70: Null payload handling is appropriate.Returning
Result.failure()if the payload isnullprevents sending empty data.
71-119: Robust branching for success/failure/retry.Each path cleans up storage where needed. This ensures data is cleared on both success and hard failure.
156-171: Foreground notification is well-implemented.Providing a foreground Notification is essential for user awareness and OS compliance.
173-190: Client instantiation and closing infinally.This ensures resources are freed after each request. However, keep in mind that a new client is re-created on each worker instance.
192-197: Sealed class for typed results is clean.Use of a sealed class for capturing success, failure, and retry states clearly conveys different outcomes.
198-239: Proper WorkManager constraints and enqueuing.The method sets expedited priority, exponential backoff, and optionally requires the network, aligning with best practices for background tasks.
app/src/main/java/app/callgate/android/modules/server/ServerService.kt (3)
6-8: Good use of dependency injection.The constructor now accepts a
ServerSettingsparameter directly which improves encapsulation and testability.
10-10: LGTM: Proper device ID initialization.Using the null-coalescing operator to only generate a device ID when needed is a good practice.
19-19: API simplification looks good.Removing the context parameter from
isActiveLiveData()simplifies the API as WebService.STATUS is likely already context-aware.app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt (2)
11-15: Well-structured dependency injection.Good use of constructor dependency injection which makes the service testable and follows SOLID principles.
45-57: Good error handling in service shutdown.The stop method properly handles exceptions during service shutdown, ensuring that both services have a chance to stop even if one fails.
app/src/main/java/app/callgate/android/App.kt (3)
5-11: Module imports aligned with architectural changes.Good addition of the necessary modules for the new architecture.
24-32: Proper Koin module registration.All required modules are correctly registered in the Koin DI container.
35-35: Clean service initialization.The OrchestratorService is properly initialized with autostart parameter, replacing the previous direct ServerService usage.
app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt (3)
13-15: Good use of Koin for dependency injection in BroadcastReceiver.Implementing KoinComponent and using property injection is a clean approach for accessing dependencies in a BroadcastReceiver.
21-22: Consider privacy implications of logging phone numbers.The app accesses the incoming phone number which requires READ_PHONE_STATE permission. While the @Suppress("DEPRECATION") annotation addresses API deprecation, consider the privacy implications when working with phone numbers.
When logging phone numbers, consider masking them in logs:
- Log.d("CallsReceiver", "Incoming call from $incomingNumber") + // Only show last 4 digits of phone number in logs + val maskedNumber = incomingNumber?.let { + if (it.length > 4) "****" + it.substring(it.length - 4) else it + } + Log.d("CallsReceiver", "Incoming call from $maskedNumber")
31-55: Comprehensive call state handling.Good use of the when expression to handle different call states and generate appropriate events. The implementation correctly handles all possible states and includes an else branch.
app/src/main/java/app/callgate/android/modules/calls/CallsService.kt (2)
23-26: Good use of dependency injection for WebHooksService.The service properly handles the new dependency through constructor injection, which follows good dependency injection practices.
47-48: Improved readability in getCall() method.Storing the telephonyManager.callState in a variable within the when expression improves code readability.
app/src/main/java/app/callgate/android/ui/HomeFragment.kt (2)
80-80: Appropriate API level check for ANSWER_PHONE_CALLS permission.Good use of takeIf to conditionally include the permission only on Android O (API 26) and above, where it was introduced.
112-113: Method signature simplification is good.Simplifying the newInstance() method to not require parameters makes the code cleaner.
README.md (17)
4-4: Title Branding Update Confirmed.
The inclusion of ™ in "Android™" enhances brand consistency and emphasizes the API’s focus.
12-14: Updated Features List.
The new list items—"Call control via HTTP API", "Real-time webhook notifications", and "Basic authentication protection"—clearly communicate the app's enhanced capabilities.
18-18: Getting Started Section Updated.
The updated header ("## 📦 Getting Started") with an icon provides a more engaging entry point for new users.
24-30: Installation Instructions Restructured.
The installation steps now feature a dedicated "First Steps" section, which improves post-installation clarity by guiding users to view credentials and change the default password.🧰 Tools
🪛 LanguageTool
[uncategorized] ~25-~25: You might be missing the article “the” here.
Context: ...e device ### Installation 1. [Download latest APK](https://github.com/call-gate-app/a...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
32-34: Core API Usage Section Update.
Renaming this section and explicitly displaying the base URL help API consumers quickly locate integration details.
36-36: Call Management Section Updated.
The header "### 📞 Call Management" effectively organizes the API operation documentation, making it easier to navigate.
43-48: Start Call API Request Example Updated.
The curl command now includes the basic authentication flag and a clearly formatted JSON payload, enhancing usability and clarity for starting a call.
49-53: Response Documentation for Start Call.
The list of potential responses (200, 400, 401, 500) is comprehensive and sets clear expectations for API behavior.
60-64: End Call API Request Example Updated.
The DELETE request example now incorporates the basic authentication flag, ensuring consistency with the Start Call example.
66-69: Response Documentation for End Call.
Documenting the responses for ending a call enhances clarity and consistency in the API reference.
70-78: Webhook System Section Added.
The new section detailing webhook events (e.g.,call:ringing,call:started,call:ended) is well organized and clearly conveys the functionality introduced by the PR.🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
73-73: Tables should be surrounded by blank lines
null(MD058, blanks-around-tables)
79-87: Webhook Configuration Documented.
The configuration table, including the base URL and endpoint descriptions, provides clear guidance for integrating with the webhook feature.
88-95: Webhook Registration Example Provided.
The curl command example for registering a webhook effectively demonstrates how to configure the webhook, aiding users in practical setup and testing.
102-107: SMSGate Compatibility Details.
The section comparing webhook structures with SMSGate—including differences in retry policies—provides valuable context for developers integrating with similar systems.
108-113: Security Best Practices Maintained.
The security guidelines emphasizing credential rotation, network restrictions, and potential encryption measures remain robust and clear.
116-118: Related Projects Section Updated.
Providing a reference to SMSGate and including a direct link helps users discover complementary solutions, which can enhance the overall ecosystem experience.
121-125: Project Status and Version Warning Clarified.
Clearly communicating that the app is in active development and noting that the API may change during the 0.x phase sets proper expectations for early adopters and contributors.
| companion object { | ||
| private val DATE_FORMAT = | ||
| SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US).apply { | ||
| timeZone = TimeZone.getTimeZone("GMT") | ||
| } | ||
| } |
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
Use ThreadLocal for SimpleDateFormat to ensure thread safety.
SimpleDateFormat is not thread-safe. Since Room converters can be called from multiple threads, this can lead to data corruption or unexpected behavior.
companion object {
- private val DATE_FORMAT =
- SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US).apply {
- timeZone = TimeZone.getTimeZone("GMT")
- }
+ private val DATE_FORMAT = ThreadLocal<SimpleDateFormat>().apply {
+ set(
+ SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US).apply {
+ timeZone = TimeZone.getTimeZone("GMT")
+ }
+ )
+ }
}Then update the date conversion methods to use:
val dateFormat = DATE_FORMAT.get()
// Use dateFormat instead of DATE_FORMAT| fun dateFromString(value: String?): Date? { | ||
| return value?.let { DATE_FORMAT.parse(it) } | ||
| } |
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
Handle date parsing exceptions and use non-deprecated API.
The parse(it) method is deprecated. Also, add error handling for parsing invalid date strings.
@TypeConverter
fun dateFromString(value: String?): Date? {
- return value?.let { DATE_FORMAT.parse(it) }
+ return value?.let {
+ try {
+ DATE_FORMAT.parse(it.toString())
+ } catch (e: Exception) {
+ null
+ }
+ }
}📝 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.
| fun dateFromString(value: String?): Date? { | |
| return value?.let { DATE_FORMAT.parse(it) } | |
| } | |
| @TypeConverter | |
| fun dateFromString(value: String?): Date? { | |
| return value?.let { | |
| try { | |
| DATE_FORMAT.parse(it.toString()) | |
| } catch (e: Exception) { | |
| null | |
| } | |
| } | |
| } |
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
♻️ Duplicate comments (3)
app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt (1)
45-57: Proper exception handling in the stop method.The stop method correctly handles exceptions for both services, ensuring that a failure in stopping one service doesn't prevent the other from stopping. This is a good practice for graceful shutdown.
app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt (2)
22-26: Add a delimiter to prevent collisions between content and timestamp.
Using direct string concatenation (content.text + timestamp) risks ambiguous signatures ifcontent.textcan end with numeric data.- val message = content.text + timestamp + val message = "${content.text}:${timestamp}"
50-56: Add error handling for cryptographic operations.
Wrapped cryptographic logic in atry-catchblock to gracefully handle exceptions and avoid unexpected crashes or partial writes.-fun generateSignature(algorithm: String, secretKey: String, payload: String): String { - val mac = Mac.getInstance(algorithm) - val secretKeySpec = SecretKeySpec(secretKey.toByteArray(charset = Charsets.UTF_8), algorithm) - mac.init(secretKeySpec) - val hash = mac.doFinal(payload.toByteArray(charset = Charsets.UTF_8)) - return hash.toHexString(HexFormat.Default) +fun generateSignature(algorithm: String, secretKey: String, payload: String): String { + return try { + val mac = Mac.getInstance(algorithm) + val secretKeySpec = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8), algorithm) + mac.init(secretKeySpec) + val hash = mac.doFinal(payload.toByteArray(Charsets.UTF_8)) + hash.toHexString(HexFormat.Default) + } catch (e: Exception) { + // Log error safely, rethrow or return fallback + throw RuntimeException("Failed to generate signature", e) + } }
🧹 Nitpick comments (7)
app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt (3)
33-37: Consider removing commented-out log code.There's commented-out code related to a logging service. If this is no longer needed, consider removing it entirely. If it's planned for future implementation, add a TODO comment explaining the plan.
-// logsSvc.insert( -// LogEntry.Priority.WARN, -// MODULE_NAME, -// "Can't start foreground services while the app is running in the background" -// ) + // TODO: Implement additional logging when LogsService is available
23-42: Consider documenting the exception propagation behavior.The
startmethod rethrows most exceptions (except the specific Android S+ exception). This means callers need to handle these exceptions, which should be documented.+ /** + * Starts webhook and server services + * + * @param context Android context + * @param autostart Whether the service should respect the autostart setting + * @throws Throwable If an error occurs during server service startup + */ fun start(context: Context, autostart: Boolean) {
1-58: Consider adding thread safety mechanisms.The class doesn't include any mechanisms to ensure thread safety if multiple components call
startorstopconcurrently. Consider adding synchronization or documenting that the class is not thread-safe.class OrchestratorService( private val settings: GeneralSettings, private val serverSvc: ServerService, private val webHooksSvc: WebHooksService, ) { + @Synchronized fun start(context: Context, autostart: Boolean) { // existing implementation } + @Synchronized fun stop(context: Context) { // existing implementation } }README.md (4)
47-55: Improved Installation Instructions
The installation steps now include a "First Steps" section that advises users to change the default password for security. Consider making minor adjustments for bullet list indentation and language (e.g., adding "the" where appropriate) to address markdownlint and LanguageTool suggestions.🧰 Tools
🪛 LanguageTool
[uncategorized] ~49-~49: You might be missing the article “the” here.
Context: ... device ### Installation 1. [Download latest APK](https://github.com/call-gate-app/a...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
🪛 markdownlint-cli2 (0.17.2)
53-53: Unordered list indentation
Expected: 0; Actual: 2(MD007, ul-indent)
54-54: Unordered list indentation
Expected: 0; Actual: 2(MD007, ul-indent)
76-82: Response Codes for Starting Calls
The responses for the "Start Call" operation are clearly enumerated. Minor punctuation refinements could further enhance consistency per static analysis feedback.🧰 Tools
🪛 LanguageTool
[uncategorized] ~78-~78: Loose punctuation mark.
Context: ...v1/calls ``` Responses: -200 OK: Call initiated - `400 Bad Request`: Inv...(UNLIKELY_OPENING_PUNCTUATION)
95-99: Response Codes for Ending Calls
The response codes for ending a call are well-documented. A quick review of the punctuation used in the list (as flagged by static analysis) might be beneficial for uniformity.🧰 Tools
🪛 LanguageTool
[uncategorized] ~97-~97: Loose punctuation mark.
Context: ... ``` Responses: -204 No Content: Call ended - `500 Internal Server Error...(UNLIKELY_OPENING_PUNCTUATION)
139-143: Webhook System Requirements Clarification
The requirements listed for the webhook system, such as having a valid SSL certificate and ensuring receiver accessibility, are appropriate. Consider reviewing line 141 for any potential wording duplication to improve clarity.🧰 Tools
🪛 LanguageTool
[duplication] ~141-~141: Possible typo: you repeated a word.
Context: ...irements:** - Valid SSL certificate on receiver - Receiver accessible from device ### Example Pay...(ENGLISH_WORD_REPEAT_RULE)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
README.md(1 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt(1 hunks)app/src/main/java/app/callgate/android/ui/HomeFragment.kt(5 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt
- app/src/main/java/app/callgate/android/ui/HomeFragment.kt
- app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt
🧰 Additional context used
🪛 LanguageTool
README.md
[uncategorized] ~49-~49: You might be missing the article “the” here.
Context: ... device ### Installation 1. [Download latest APK](https://github.com/call-gate-app/a...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~78-~78: Loose punctuation mark.
Context: ...v1/calls ``` Responses: - 200 OK: Call initiated - `400 Bad Request`: Inv...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~97-~97: Loose punctuation mark.
Context: ... ``` Responses: - 204 No Content: Call ended - `500 Internal Server Error...
(UNLIKELY_OPENING_PUNCTUATION)
[duplication] ~141-~141: Possible typo: you repeated a word.
Context: ...irements:** - Valid SSL certificate on receiver - Receiver accessible from device ### Example Pay...
(ENGLISH_WORD_REPEAT_RULE)
🪛 markdownlint-cli2 (0.17.2)
README.md
53-53: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
54-54: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
🔇 Additional comments (24)
app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt (1)
1-15: Well-structured service with clean dependency injection.The OrchestratorService is well-designed with proper dependency injection and encapsulation. This approach makes the code testable and follows good architectural principles.
app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt (1)
10-16: Well-Structured Plugin Creation.Initializing the plugin with clear, self-descriptive property names (
hmacAlgorithm,signatureHeaderName, etc.) fosters straightforward configuration. No issues here.README.md (22)
1-4: Update Title and Tagline
The README title now includes the trademark symbol and the tagline is refreshed, which enhances the project’s branding.
6-7: Enhanced Application Description
The updated description clearly explains that CallGate provides programmatic control of phone calls for automation without handling audio, aligning well with the new webhook support.
9-11: Clear Audio Handling Disclaimer
The warning about audio handling effectively sets user expectations regarding the app’s functionality.
12-31: Updated Table of Contents
The Table of Contents now includes a section for the Webhook System and has been reorganized for improved navigation. Please verify that all internal links correctly correspond to their sections.
32-39: Refreshed Features Section
The features list now highlights “Real-time webhook notifications” along with call control and basic authentication. This update is in direct support of the new webhook functionality.
40-46: Organized Getting Started & Prerequisites
The "Getting Started" and "Prerequisites" sections are well-structured, making it clear what is required before installation.
56-59: Core API Usage Clarification
The "Core API Usage" section now clearly specifies the base URL and directs users to the API endpoints. This clarity aids integration efforts.
60-66: Start Call Endpoint Details
The "Start Call" section accurately documents the POST endpoint along with a code block that showcases the proper HTTP request format.
68-74: Well-Demonstrated cURL Example for Starting Calls
The curl command example includes all required flags and shows the correct JSON structure for the call initiation.
83-94: End Active Call Endpoint Details
The "End Active Call" section details the DELETE request clearly, including a corresponding cURL example that uses proper authentication.
100-101: Introduction of the Webhook System
The new "Webhook System" header clearly signals the addition of webhook features, which is the primary focus of this PR.
102-109: Webhook Events Table
The events table is concise and easy to read, providing clear information on the different webhook events likecall:ringing,call:started, andcall:ended.
110-119: Detailed Webhook Configuration
The configuration section efficiently communicates the available HTTP methods and endpoints for managing webhooks. The table format is effective and aligns with standard REST API documentation practices.
120-137: Comprehensive cURL Examples for Webhook Operations
The curl examples for registering, retrieving, and deleting webhooks are thorough and provide clear guidance for interacting with the webhook API.
144-156: Example JSON Payload for Webhooks
The JSON payload example is formatted correctly and clearly illustrates the data structure expected by the webhook system.
157-162: SMSGate Compatibility Section
The section on SMSGate Compatibility explains how the webhook request structure and signing mechanism are consistent with SMSGate standards, which is valuable for developers integrating with similar systems.
163-167: Key Differences Highlighted
The "Key differences" list succinctly outlines the behavioral distinctions (linear retry policy and maximum retry attempts) compared to SMSGate, easing user comprehension of the system’s limits.
168-173: Security Best Practices Overview
The security advice, including regular credential rotation, network restrictions, and encryption considerations, is pertinent given the critical nature of call and webhook data.
174-178: Related Projects Section
Linking to SMSGate and providing context on related projects adds valuable ecosystem information for users and contributors.
179-182: Project Status Communication
The project status is clearly stated, emphasizing that the app is in active development and not yet production-ready, which sets appropriate expectations.
186-195: Contributing Guidelines Clarity
The contributing guidelines provide a straightforward, step-by-step process for potential contributors. This clarity encourages community engagement.🧰 Tools
🪛 LanguageTool
[style] ~192-~192: Consider using a more formal and expressive alternative to ‘amazing’.
Context: ...re/amazing-feature) 3. Commit changes (git commit -m 'Add amazing feature') 4. Push to branch (git push...(AWESOME)
196-199: License Information Completeness
The license section appropriately directs users to the full license text and aligns with open source best practices.
app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt
Show resolved
Hide resolved
46e67c2 to
51b8494
Compare
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: 0
♻️ Duplicate comments (7)
app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt (3)
23-26: Add error handling for GET route.The GET route lacks error handling for potential exceptions from the service layer. Consider adding a try-catch block to handle possible exceptions and return appropriate error responses.
private fun Route.webhooksRoutes() { get { + try { call.respond(webHooksService.select(EntitySource.Local)) + } catch (e: Exception) { + call.respond(HttpStatusCode.InternalServerError, mapOf("error" to e.message)) + } }
27-32: Add error handling for POST route.The POST route lacks error handling for potential exceptions from the service layer. Additionally, consider adding validation for the incoming webhook data.
post { + try { val webhook = call.receive<WebHookDTO>() + // Optional: Add validation for webhook data val updated = webHooksService.replace(EntitySource.Local, webhook) call.respond(HttpStatusCode.Created, updated) + } catch (e: Exception) { + call.respond(HttpStatusCode.InternalServerError, mapOf("error" to e.message)) + } }
33-37: Add error handling for DELETE route.Similar to the GET and POST routes, the DELETE route should also handle potential exceptions from the service layer.
delete("/{id}") { val id = call.parameters["id"] ?: return@delete call.respond(HttpStatusCode.BadRequest) + try { webHooksService.delete(EntitySource.Local, id) call.respond(HttpStatusCode.NoContent) + } catch (e: Exception) { + call.respond(HttpStatusCode.InternalServerError, mapOf("error" to e.message)) + } }app/src/main/java/app/callgate/android/modules/server/ServerService.kt (1)
21-31: Repeated concern about device ID generation.
The current implementation useshashCode()ondeviceNamewithout error handling forpackageInfo. This mirrors a previously noted approach. It still risks collisions across devices and unpredictableMANUFACTURER/PRODUCTvalues. Additionally, no fallback is provided ifgetPackageInfofails. Please consider using UUID-based generation or a more robust approach, as suggested previously.app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt (3)
18-25: Document or remove commented-out lines for clarity.This is a repeat of a previous suggestion to either explain or remove the commented-out
gatewaySettingsreference. The same concern still applies.
26-32: Implement or document the lifecycle methods.The
startandstopmethods remain no-ops with commented-out logic. Consider either fully implementing them or providing a clear explanation via doc comments regarding their intended usage.
86-113: Remove or clarify commented-out code.This is a repeat of a previous suggestion regarding the commented logic. Either finalize or remove these lines for a cleaner, more understandable implementation.
🧹 Nitpick comments (14)
app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt (1)
1-39: Consider adding logging for API operations.For better debugging and monitoring capabilities, consider adding logging for API operations. This would help track API usage and troubleshoot issues in production.
package app.callgate.android.modules.server.routes import app.callgate.android.domain.EntitySource import app.callgate.android.modules.webhooks.WebHooksService import app.callgate.android.modules.webhooks.domain.WebHookDTO import io.ktor.http.HttpStatusCode import io.ktor.server.request.receive import io.ktor.server.response.respond import io.ktor.server.routing.Route import io.ktor.server.routing.delete import io.ktor.server.routing.get import io.ktor.server.routing.post +import org.slf4j.LoggerFactory class WebhooksRoutes( private val webHooksService: WebHooksService, ) { + private val logger = LoggerFactory.getLogger(WebhooksRoutes::class.java) + fun register(routing: Route) { routing.apply { webhooksRoutes() } } private fun Route.webhooksRoutes() { get { + logger.debug("Received GET request for webhooks") try { call.respond(webHooksService.select(EntitySource.Local)) + logger.debug("Successfully responded with webhooks list") } catch (e: Exception) { + logger.error("Error while getting webhooks", e) call.respond(HttpStatusCode.InternalServerError, mapOf("error" to e.message)) } } // Similar logging for other routesapp/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt (1)
16-43: Check for missing MODULE_NAME definition and remove commented-out code if unneeded.
- You use
MODULE_NAMEin logs, but it’s not declared in this snippet. Include a constant or companion object to avoid compilation issues.- The commented-out
logsSvc.insert(...)calls are not used. If they are no longer necessary, consider removing them to keep the code clean.app/src/main/res/values/strings.xml (1)
25-119: Extensive Localization & UI Strings UpdateThis large block (lines 25–119) introduces many new string resources covering various aspects of the UI—including battery optimization messages, button labels, error messages, instructions, and settings labels. A few specific points to consider:
- Placeholder Verification: Ensure that all placeholders (such as
%1$sand%2$d) are accurately positioned and will be correctly substituted at runtime.- Punctuation & Ellipsis Consistency: Verify the consistent use of punctuation and ellipsis (e.g., the
…in strings likecloud_server_dotdotdotandwebhooks_dotdotdot).- HTML Formatting: Strings containing HTML-like anchors (example:
settings_local_address_is) should be validated to ensure they render securely and as intended in the UI.- Tone & Clarity: Some texts (e.g.,
online_status_at_the_cost_of_battery_life) might benefit from rewording for clarity—consider phrasing like “Online status may reduce battery life” to improve understanding.Overall, these additions are a solid enhancement to the app’s internationalization effort, especially in support of new features like webhook handling.
app/src/main/java/app/callgate/android/modules/calls/CallsService.kt (1)
74-74: Repeated@Suppress("DEPRECATION").Double-check if this is still required for
telecomManager.endCall()on newer Android versions; removing it might reduce clutter if no longer needed.README.md (5)
49-49: Missing article in Installation step.Static analysis suggests using “the” before “latest APK.” For instance, “Download the latest APK” is more grammatically natural.
Here's a possible fix:
-1. [Download latest APK](https://github.com/call-gate-app/android-app/releases/latest) +1. [Download the latest APK](https://github.com/call-gate-app/android-app/releases/latest)🧰 Tools
🪛 LanguageTool
[uncategorized] ~49-~49: You might be missing the article “the” here.
Context: ... device ### Installation 1. [Download latest APK](https://github.com/call-gate-app/a...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
53-54: Unordered list indentation.Markdown lint (MD007) flags indentation here. Adjusting indentation to 0 or aligning list levels will help maintain consistent formatting.
- - Settings → Server to view credentials - - Change the random password to something secure, if necessary +- Settings → Server to view credentials +- Change the random password to something secure, if necessary🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
53-53: Unordered list indentation
Expected: 0; Actual: 2(MD007, ul-indent)
54-54: Unordered list indentation
Expected: 0; Actual: 2(MD007, ul-indent)
78-78: Loose punctuation mark.Check punctuation usage in the “Responses:” line to ensure consistency.
Consider replacing with a colon or removing extra punctuation to match the style used elsewhere.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~78-~78: Loose punctuation mark.
Context: ...v1/calls ``` Responses: -200 OK: Call initiated - `400 Bad Request`: Inv...(UNLIKELY_OPENING_PUNCTUATION)
97-97: Loose punctuation mark.Similar punctuation style issue in the subsequent “Responses:” line. Keeping punctuation consistent across headings is recommended.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~97-~97: Loose punctuation mark.
Context: ... ``` Responses: -204 No Content: Call ended - `404 Not Found`: No ringin...(UNLIKELY_OPENING_PUNCTUATION)
142-142: Possible word repetition.Static analysis flagged a repeated word. Please check for any duplicated terms like “from device device” or “the the.” Removing the duplicate ensures clarity.
-Receiver accessible from device device +Receiver accessible from device🧰 Tools
🪛 LanguageTool
[duplication] ~142-~142: Possible typo: you repeated a word.
Context: ...irements:** - Valid SSL certificate on receiver - Receiver accessible from device ### Example Pay...(ENGLISH_WORD_REPEAT_RULE)
app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt (1)
49-56: HMAC signature generation looks solid.Using UTF-8 explicitly is essential. You might add logging or specific try/catch to handle unexpected cryptographic failures, though returning an exception from
generateSignatureis sufficient for many use cases.app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (1)
46-47: Consider removing commented-out code.The
logsSvcinjection is commented out. If no longer needed, remove it to declutter the worker.app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt (3)
44-53: Consider generating IDs for new webhooks automatically.Currently, the
syncmethod requires eachWebHookDTOto have a non-nullid, causing an error if missing. For a more user-friendly experience, optionally auto-generate the ID if it’s not provided.
55-80: Rename method for clarity.“replace” could be misread; the method effectively creates or updates entries. Consider a name like
upsertWebhookorcreateOrUpdateWebhookto better reflect its behavior.
100-112: Add error handling or logging for the worker call.
SendWebhookWorker.startis invoked without error handling or logging. Consider wrapping it for potential failures or adding logs to aid in debugging webhook delivery issues.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (52)
README.md(1 hunks)app/build.gradle.kts(4 hunks)app/schemas/app.callgate.android.modules.db.AppDatabase/1.json(1 hunks)app/src/main/AndroidManifest.xml(1 hunks)app/src/main/java/app/callgate/android/App.kt(2 hunks)app/src/main/java/app/callgate/android/domain/EntitySource.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsService.kt(3 hunks)app/src/main/java/app/callgate/android/modules/calls/events/CallEvent.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/Converters.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/notifications/NotificationsService.kt(2 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/ServerService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt(2 hunks)app/src/main/java/app/callgate/android/modules/server/WebService.kt(6 hunks)app/src/main/java/app/callgate/android/modules/server/routes/CallsRoutes.kt(2 hunks)app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt(1 hunks)app/src/main/java/app/callgate/android/modules/settings/Module.kt(2 hunks)app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHook.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookDTO.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEvent.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEventDTO.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt(1 hunks)app/src/main/java/app/callgate/android/ui/HomeFragment.kt(5 hunks)app/src/main/java/app/callgate/android/ui/settings/BasePreferenceFragment.kt(2 hunks)app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt(1 hunks)app/src/main/res/drawable-notnight/ic_no_internet.xml(1 hunks)app/src/main/res/drawable-notnight/ic_retry.xml(1 hunks)app/src/main/res/drawable-notnight/ic_signing_key.xml(1 hunks)app/src/main/res/drawable-notnight/ic_webhook.xml(1 hunks)app/src/main/res/drawable/ic_no_internet.xml(1 hunks)app/src/main/res/drawable/ic_retry.xml(1 hunks)app/src/main/res/drawable/ic_signing_key.xml(1 hunks)app/src/main/res/drawable/ic_webhook.xml(1 hunks)app/src/main/res/drawable/notif_server.xml(1 hunks)app/src/main/res/drawable/notif_webhook.xml(1 hunks)app/src/main/res/values/strings.xml(2 hunks)app/src/main/res/xml/root_preferences.xml(1 hunks)app/src/main/res/xml/webhooks_preferences.xml(1 hunks)build.gradle.kts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (42)
- app/src/main/res/drawable-notnight/ic_no_internet.xml
- app/src/main/res/drawable/ic_retry.xml
- app/src/main/res/drawable-notnight/ic_retry.xml
- app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt
- app/src/main/java/app/callgate/android/modules/db/Module.kt
- app/src/main/res/drawable/notif_webhook.xml
- app/src/main/res/drawable/ic_webhook.xml
- app/src/main/AndroidManifest.xml
- app/src/main/java/app/callgate/android/domain/EntitySource.kt
- app/src/main/java/app/callgate/android/modules/webhooks/Module.kt
- app/src/main/res/drawable-notnight/ic_webhook.xml
- app/src/main/java/app/callgate/android/ui/settings/BasePreferenceFragment.kt
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookDTO.kt
- app/src/main/res/drawable-notnight/ic_signing_key.xml
- app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt
- app/src/main/res/drawable/ic_no_internet.xml
- app/src/main/java/app/callgate/android/modules/calls/events/CallEvent.kt
- app/src/main/res/drawable/ic_signing_key.xml
- app/src/main/res/drawable/notif_server.xml
- app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt
- app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt
- app/src/main/java/app/callgate/android/modules/server/Module.kt
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEvent.kt
- build.gradle.kts
- app/src/main/java/app/callgate/android/modules/settings/Module.kt
- app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt
- app/src/main/java/app/callgate/android/modules/server/routes/CallsRoutes.kt
- app/src/main/java/app/callgate/android/modules/webhooks/db/WebHook.kt
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEventDTO.kt
- app/src/main/java/app/callgate/android/modules/server/WebService.kt
- app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt
- app/src/main/res/xml/webhooks_preferences.xml
- app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt
- app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt
- app/src/main/java/app/callgate/android/modules/notifications/NotificationsService.kt
- app/src/main/java/app/callgate/android/ui/HomeFragment.kt
- app/src/main/res/xml/root_preferences.xml
- app/build.gradle.kts
- app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt
- app/schemas/app.callgate.android.modules.db.AppDatabase/1.json
- app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt
- app/src/main/java/app/callgate/android/modules/db/Converters.kt
🧰 Additional context used
🧬 Code Graph Analysis (2)
app/src/main/java/app/callgate/android/App.kt (2)
app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt (1)
get(32-46)app/src/main/java/app/callgate/android/modules/settings/KeyValueStorage.kt (2)
get(8-8)get(12-14)
app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt (1)
app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt (1)
delete(82-84)
🪛 LanguageTool
README.md
[uncategorized] ~49-~49: You might be missing the article “the” here.
Context: ... device ### Installation 1. [Download latest APK](https://github.com/call-gate-app/a...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~78-~78: Loose punctuation mark.
Context: ...v1/calls ``` Responses: - 200 OK: Call initiated - `400 Bad Request`: Inv...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~97-~97: Loose punctuation mark.
Context: ... ``` Responses: - 204 No Content: Call ended - `404 Not Found`: No ringin...
(UNLIKELY_OPENING_PUNCTUATION)
[duplication] ~142-~142: Possible typo: you repeated a word.
Context: ...irements:** - Valid SSL certificate on receiver - Receiver accessible from device ### Example Pay...
(ENGLISH_WORD_REPEAT_RULE)
🪛 markdownlint-cli2 (0.17.2)
README.md
53-53: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
54-54: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
🔇 Additional comments (30)
app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt (1)
14-21: Well-structured class for managing webhook routes.The WebhooksRoutes class follows good design principles by taking its dependency (WebHooksService) through constructor injection and providing a clear registration method. This makes the class both testable and reusable.
app/src/main/java/app/callgate/android/App.kt (3)
5-11: Architectural shift to include new modules for webhooks support.The imports have been updated to include necessary modules for the new webhook functionality and architectural changes. The app is shifting from using
ServerServiceandGeneralSettingsto using a more comprehensiveOrchestratorServicealong with database and webhook modules.
24-32: Koin dependency injection properly configured for new modules.The Koin dependency injection setup has been correctly updated to include the new modules:
dbModule,webhooksModule, andorchestratorModule. This configuration will make these services available throughout the application.
35-35:Details
✅ Verification successful
Verify behavior change in service initialization.
The initialization logic has changed from conditionally starting
ServerServicebased on user settings to unconditionally startingOrchestratorServicewith a hardcodedtrueparameter. Ensure this doesn't remove any user configuration options that were previously available.
🏁 Script executed:
#!/bin/bash # Check if OrchestratorService handles user configuration internally rg -A 10 "class OrchestratorService" --type kotlinLength of output: 1294
Service Initialization Behavior Verified:
The refactored code still preserves user configuration. Althoughget<OrchestratorService>().start(this, true)now unconditionally passestrue, theOrchestratorService.startmethod immediately checks:if (autostart && !settings.autostart) { return }This means that if the user's settings disable autostart, the initialization won’t proceed, maintaining the previous behavior. No user configuration options have been inadvertently removed.
app/src/main/java/app/callgate/android/modules/server/ServerService.kt (4)
4-4: No issues with the new import.
6-8: Constructor injection looks good.
10-11: Consider handling potential errors when retrieving package info.
Usingcontext.packageManager.getPackageInfo(…)may throw an exception on some devices (e.g., if the package info is unavailable). Wrap this call in atry-catchblock or check for nullability to avoid a potential crash.
19-20: Straightforward approach to exposing status.app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt (4)
1-2: Package declaration is acceptable.
3-10: Imports for new classes and exceptions look appropriate.
11-15: Constructor-based dependency injection is a clean design choice.
45-57: Exception handling on service stop is well-implemented; verify MODULE_NAME usage.
Good job adding try-catch blocks for each service stop call. Make sure theMODULE_NAMEconstant is defined to prevent referencing an undefined symbol.app/src/main/res/values/strings.xml (3)
3-3: Reintroduction of App Metadata StringsThe new string resources
app_version_build(line 3) andinformation(line 5) have been re-added. Please ensure that their values align with the app’s branding guidelines and are consistent with other localized versions across the project.Also applies to: 5-5
14-14: New Webhook Status IndicatorThe addition of
sending_webhook(line 14) provides a user-facing message to indicate that a webhook is in progress. Verify that the ellipsis character (…) renders correctly on all supported devices and is consistent with similar UI elements in the app.
20-24: Notification & API Configuration StringsThe new strings in this block—
call_gate_notifications(line 20),address_is(line 22),api_url(line 23), andapi_url_private_token_credentials_etc(line 24)—offer important messaging for notifications and API configuration, which ties into the new webhook functionality. Please double-check that placeholder formatting (e.g.,%1$s) is correctly implemented and that the naming conventions for API-related keys remain clear and coherent throughout the codebase.app/src/main/java/app/callgate/android/modules/calls/CallsService.kt (5)
12-19: No concerns about the new imports.All newly imported classes (e.g.,
Log,CallEvent,CallEventPayload,WebHooksService,WebHookEvent) seem relevant and are used within the code. No duplication or unused imports detected.
24-25: Constructor injection is appropriate.Passing
WebHooksServicevia the constructor aligns with dependency injection best practices, improving testability and maintainability.
41-41: Verify necessity of@Suppress("DEPRECATION").While the deprecation suppression could be valid for older API calls, consider confirming whether any modern alternative is suitable.
48-48: Concise call state retrieval.Using
val callState = telephonyManager.callStateinside thewhenclause is a clean approach, enhancing readability. Great job.
78-93: Webhooks emission with coarse error handling.The
processEventmethod correctly distinguishes event types and emits them viawebHooksService. Thetry/catchblock captures allThrowable, but consider whether more targeted exception handling might offer clearer diagnostics for network vs. internal errors. Otherwise, this error logging provides a good safety net.app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt (1)
17-39: Conditional content transformation is clear and extensible.The plugin correctly checks if the outgoing content is
TextContent, then appends a timestamp for signing. Consider whether you need to handle other content types (e.g., multipart). If not, this is good for text-based JSON.app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (8)
43-44: Clear naming and structure.Extending
CoroutineWorkerand naming itSendWebhookWorkermakes it easy to discover. In large codebases, employing consistent naming for background tasks fosters clarity.
49-50: Dependency injection forWebhooksSettingsandTemporaryStorage.Injecting these dependencies is straightforward and keeps the worker configurable. Good use of Koin.
52-119:doWork()logic thoroughly covers success, failure, and retry paths.Each path (success/failure/retry) is well-defined. Logging is commented out, but reintroducing it could enhance observability. Also confirm that removing data from storage only when necessary aligns with your design.
121-154: Robust HTTP request logic with fallback.The
sendDatamethod covers multiple exception types (e.g.,IllegalArgumentException,JSONException) and returns either failure or retry accordingly. This approach is good for ensuring robust error handling. Consider logging these errors or tracing requests for debugging.
156-171: Foreground service usage is appropriately designed.
getForegroundInfo()andcreateForegroundInfo()follow Android best practices for background tasks, ensuring the system doesn’t kill your worker prematurely. Nice use of the Notification API.
173-190: HTTP client configuration is comprehensive.
- Timeouts are clearly set.
ContentNegotiationwithgsonis appropriate for JSON.PayloadSigningPluginis installed with thesecretKeyProvider.No concurrency issues identified.
192-196: Use of sealed class for result handling is clean.Defining
Success,Failure, andRetryprovides clarity and type safety. This is more expressive than just returning booleans or generic results.
198-239: Companion object method for enqueuing work.Placing
startinside the companion object is a good approach, avoiding top-level functions. TheTemporaryStorageusage to store data frames is a neat pattern.app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt (1)
55-60: Verify handling of non-127.0.0.1 local addresses.The code only allows
http://127.0.0.1for HTTP-based endpoints. If you need additional addresses (e.g.,http://localhost), confirm whether this is intentional or if broader local address support is needed.
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: 0
🧹 Nitpick comments (9)
README.md (9)
1-7: Header Branding and Project Introduction
The updated header now clearly displays the project title with an appealing phone emoji and a trademark symbol, and the brief description sets the tone for the project. Please verify that the trademark symbol (™) complies with your branding guidelines and that the introductory text reflects all recent changes accurately.
48-56: Installation Instructions & Markdown Indentation
The installation section now includes a "First Steps" subsection with explicit instructions for securing the default password. Note that the unordered list items (lines 54-55) have extra indentation, which may trigger markdown lint warnings (MD007). Consider reducing their indent to match the expected style.🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
54-54: Unordered list indentation
Expected: 0; Actual: 2(MD007, ul-indent)
55-55: Unordered list indentation
Expected: 0; Actual: 2(MD007, ul-indent)
69-76: cURL Example for Starting a Call
The cURL example now demonstrates proper usage of authentication and JSON payload formatting for initiating a call. Ensure that the sample phone number (+1234567890) adheres to the required format and that the backslashes for line continuations work as expected across different shells.
77-83: API Response Details for Start Call
The responses section clearly outlines the possible HTTP responses including success and error codes. Minor punctuation or formatting tweaks might be considered to ensure consistency with other sections.🧰 Tools
🪛 LanguageTool
[uncategorized] ~79-~79: Loose punctuation mark.
Context: ...v1/calls ``` Responses: -200 OK: Call initiated - `400 Bad Request`: Inv...(UNLIKELY_OPENING_PUNCTUATION)
96-101: API Response Details for End Call
The response codes for terminating a call are clearly listed and match the expected outcomes. Consider a quick check to ensure the phrasing is consistent with the start call responses.🧰 Tools
🪛 LanguageTool
[uncategorized] ~98-~98: Loose punctuation mark.
Context: ... ``` Responses: -204 No Content: Call ended - `404 Not Found`: No ringin...(UNLIKELY_OPENING_PUNCTUATION)
112-115: Webhook Configuration Section
The configuration section specifies the base URL for webhooks clearly. It might be helpful to add a note emphasizing that<device-ip>should be replaced with the actual IP address of the device.
141-145: Webhook Requirements Clarity
The "Requirements" section lists conditions like having a valid SSL certificate and ensuring the receiver is accessible. Consider rephrasing "- Valid SSL certificate on receiver" to improve clarity (e.g., "Receiver must have a valid SSL certificate").🧰 Tools
🪛 LanguageTool
[duplication] ~143-~143: Possible typo: you repeated a word.
Context: ...irements:** - Valid SSL certificate on receiver - Receiver accessible from device ### Example Pay...(ENGLISH_WORD_REPEAT_RULE)
170-175: Security Best Practices Update
The security recommendations are succinct and include important practices like credential rotation and network restrictions. You might consider adding specific details on encryption methods if applicable.
190-191: Contributing Section Update
The opening of the contributing section has been updated to warmly welcome contributions. Double-check that the example branch name (feature/amazing-feature) aligns with your project's current contribution guidelines.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
README.md(1 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md
[uncategorized] ~79-~79: Loose punctuation mark.
Context: ...v1/calls ``` Responses: - 200 OK: Call initiated - `400 Bad Request`: Inv...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~98-~98: Loose punctuation mark.
Context: ... ``` Responses: - 204 No Content: Call ended - `404 Not Found`: No ringin...
(UNLIKELY_OPENING_PUNCTUATION)
[duplication] ~143-~143: Possible typo: you repeated a word.
Context: ...irements:** - Valid SSL certificate on receiver - Receiver accessible from device ### Example Pay...
(ENGLISH_WORD_REPEAT_RULE)
🪛 markdownlint-cli2 (0.17.2)
README.md
54-54: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
55-55: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
🔇 Additional comments (15)
README.md (15)
9-10: No Audio Handling Notice
The notice regarding "No Audio Handling" is clearly emphasized with an appropriate warning emoji and bold text. This effectively communicates that call audio is not managed by the app.
12-30: Updated Table of Contents
The table of contents has been enhanced to include new sections such as the "Webhook System." This helps users to quickly navigate the updated documentation. Please double-check that all anchor links work as expected.
34-37: Enhanced Features Section
The features list now includes "Call control via HTTP API," "USSD support," "Real-time webhook notifications," and "Basic authentication protection." These additions provide a clear summary of the new functionality. Verify that these features are referenced correctly in other parts of the documentation.
41-42: Reorganized Getting Started Header
The "Getting Started" section header has been reintroduced, which improves the logical flow of the documentation.
57-60: Core API Usage Section Update
The "Core API Usage" section, including the base URL update (http://<device-ip>:8084/api/v1), is clear and easy to understand. This sets a solid foundation for the detailed API examples that follow.
65-68: Start Call API HTTP Example
The HTTP snippet for starting a call is concise. Please confirm that thePOST /callsrequest example aligns with the backend implementation and that the placeholder format meets your specifications.
85-95: End Active Call API Example
The DELETE request example for ending an active call is well documented. The provided cURL command, including its authentication flag, should be verified against the latest API design.
102-111: Webhook System Overview
The newly introduced "Webhook System" section is presented clearly, with an events table that outlines each webhook event likecall:ringing,call:started, andcall:ended. This provides a solid framework for understanding webhook notifications.
116-121: Webhook Endpoints Table
The table clearly defines the HTTP methods, endpoints, and their descriptions for managing webhooks. This structured presentation is very helpful to users.
122-139: Webhook cURL Examples
The examples for registering, retrieving, and deleting webhooks are comprehensive. Verify that the JSON payload in the POST command and the endpoint paths are fully aligned with the API implementation.
146-158: Example Payload for Webhooks
The provided JSON example illustrates the expected webhook payload clearly. Make sure that the key names and sample data are consistent with what the backend sends in production environments.
160-169: SMSGate Compatibility Section
This section effectively explains how the webhook request structure aligns with SMSGate webhooks and highlights key differences, such as the retry policy. Reconfirm that the external link to the SMSGate documentation is up-to-date.
176-180: Related Projects Section
The related projects section now features SMSGate with a direct link. This clear cross-reference can help users discover complementary tools.
181-184: Project Status Update
The project status note now specifies that the app is in active development and not yet ready for production. This clear communication helps set appropriate user expectations.
185-187: Version Warning Clarification
The version warning is visibly highlighted, reminding users that the API may change during the 0.x phase. This is an important caution for early adopters.
5cb2451 to
23f77de
Compare
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: 0
♻️ Duplicate comments (2)
app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt (2)
26-32: [Duplicate from previous review] Document or remove commented lifecycle code.The
startandstopmethods remain no-ops with commented code blocks. This matches a prior review comment. Consider implementing or clearly documenting the intended behavior.
86-93: [Duplicate from previous review] Clean up or clarify commented condition checks.Lines 86-93 contain commented logic for skipping event emission if certain sources are disabled. Decide whether to reintroduce or remove them to keep codebase consistent.
🧹 Nitpick comments (4)
README.md (2)
54-55: Fix list indentation for MD compliance.Markdownlint highlights these lines (54-55) for improper indentation. Adjust indentation to ensure consistent list formatting.
Apply this diff to correct the indentation:
-4. **First Steps:** - - Settings → Server to view credentials - - Change the random password +4. **First Steps:** + - Settings → Server to view credentials + - Change the random password🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
54-54: Unordered list indentation
Expected: 0; Actual: 2(MD007, ul-indent)
55-55: Unordered list indentation
Expected: 0; Actual: 2(MD007, ul-indent)
79-79: Remove loose punctuation to satisfy style guidelines.Static analysis flags lines 79 and 98 (
**Responses:**) for punctuation style. Consider removing extra punctuation or spacing to resolve these warnings.Possible fix:
-**Responses:** +**Responses**Also applies to: 98-98
🧰 Tools
🪛 LanguageTool
[uncategorized] ~79-~79: Loose punctuation mark.
Context: ...v1/calls ``` Responses: -200 OK: Call initiated - `400 Bad Request`: Inv...(UNLIKELY_OPENING_PUNCTUATION)
app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (2)
47-48: Determine the fate of the commented-out logging code.Large sections of commented-out logs could improve debugging if reintroduced, or be removed to keep the codebase clean.
-// private val logsSvc: LogsService by inject() ... -// logsSvc.insert( -// priority = LogEntry.Priority.ERROR, -// ... -// ) +// Reintroduce logs if needed for debugging or remove them to reduce clutter.Also applies to: 59-68, 73-82, 90-99, 107-117
205-234: Request tests for worker invocation logic.Consider adding unit or integration tests to ensure
SendWebhookWorker.start()is triggered and behaves as expected under various conditions (e.g., no internet, invalid URL, etc.).Do you want me to generate stubs that cover these test scenarios?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (52)
README.md(1 hunks)app/build.gradle.kts(4 hunks)app/schemas/app.callgate.android.modules.db.AppDatabase/1.json(1 hunks)app/src/main/AndroidManifest.xml(1 hunks)app/src/main/java/app/callgate/android/App.kt(2 hunks)app/src/main/java/app/callgate/android/domain/EntitySource.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsService.kt(3 hunks)app/src/main/java/app/callgate/android/modules/calls/events/CallEvent.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/Converters.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/notifications/NotificationsService.kt(2 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/ServerService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt(2 hunks)app/src/main/java/app/callgate/android/modules/server/WebService.kt(6 hunks)app/src/main/java/app/callgate/android/modules/server/routes/CallsRoutes.kt(2 hunks)app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt(1 hunks)app/src/main/java/app/callgate/android/modules/settings/Module.kt(2 hunks)app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHook.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookDTO.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEvent.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEventDTO.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt(1 hunks)app/src/main/java/app/callgate/android/ui/HomeFragment.kt(5 hunks)app/src/main/java/app/callgate/android/ui/settings/BasePreferenceFragment.kt(2 hunks)app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt(1 hunks)app/src/main/res/drawable-notnight/ic_no_internet.xml(1 hunks)app/src/main/res/drawable-notnight/ic_retry.xml(1 hunks)app/src/main/res/drawable-notnight/ic_signing_key.xml(1 hunks)app/src/main/res/drawable-notnight/ic_webhook.xml(1 hunks)app/src/main/res/drawable/ic_no_internet.xml(1 hunks)app/src/main/res/drawable/ic_retry.xml(1 hunks)app/src/main/res/drawable/ic_signing_key.xml(1 hunks)app/src/main/res/drawable/ic_webhook.xml(1 hunks)app/src/main/res/drawable/notif_server.xml(1 hunks)app/src/main/res/drawable/notif_webhook.xml(1 hunks)app/src/main/res/values/strings.xml(2 hunks)app/src/main/res/xml/root_preferences.xml(1 hunks)app/src/main/res/xml/webhooks_preferences.xml(1 hunks)build.gradle.kts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt
🚧 Files skipped from review as they are similar to previous changes (47)
- app/src/main/java/app/callgate/android/domain/EntitySource.kt
- app/src/main/res/drawable-notnight/ic_signing_key.xml
- app/src/main/java/app/callgate/android/modules/db/Module.kt
- app/src/main/res/drawable-notnight/ic_retry.xml
- app/src/main/res/drawable/ic_no_internet.xml
- app/src/main/res/drawable/ic_retry.xml
- app/src/main/res/drawable-notnight/ic_no_internet.xml
- app/src/main/res/drawable-notnight/ic_webhook.xml
- app/src/main/res/drawable/notif_server.xml
- app/src/main/java/app/callgate/android/modules/server/routes/CallsRoutes.kt
- app/src/main/res/drawable/notif_webhook.xml
- app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt
- app/src/main/java/app/callgate/android/ui/settings/BasePreferenceFragment.kt
- app/src/main/res/drawable/ic_webhook.xml
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEvent.kt
- app/src/main/AndroidManifest.xml
- app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEventDTO.kt
- app/src/main/java/app/callgate/android/modules/settings/Module.kt
- app/src/main/java/app/callgate/android/modules/webhooks/db/WebHook.kt
- build.gradle.kts
- app/src/main/java/app/callgate/android/modules/webhooks/Module.kt
- app/src/main/java/app/callgate/android/modules/server/Module.kt
- app/src/main/res/drawable/ic_signing_key.xml
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookDTO.kt
- app/src/main/java/app/callgate/android/modules/server/WebService.kt
- app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt
- app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt
- app/src/main/java/app/callgate/android/modules/calls/events/CallEvent.kt
- app/schemas/app.callgate.android.modules.db.AppDatabase/1.json
- app/src/main/java/app/callgate/android/modules/server/ServerService.kt
- app/src/main/java/app/callgate/android/modules/notifications/NotificationsService.kt
- app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt
- app/src/main/java/app/callgate/android/modules/calls/CallsService.kt
- app/src/main/res/xml/webhooks_preferences.xml
- app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt
- app/src/main/res/xml/root_preferences.xml
- app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt
- app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt
- app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt
- app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt
- app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt
- app/build.gradle.kts
- app/src/main/java/app/callgate/android/ui/HomeFragment.kt
- app/src/main/java/app/callgate/android/modules/db/Converters.kt
- app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt
- app/src/main/res/values/strings.xml
🧰 Additional context used
🪛 LanguageTool
README.md
[uncategorized] ~79-~79: Loose punctuation mark.
Context: ...v1/calls ``` Responses: - 200 OK: Call initiated - `400 Bad Request`: Inv...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~98-~98: Loose punctuation mark.
Context: ... ``` Responses: - 204 No Content: Call ended - `404 Not Found`: No ringin...
(UNLIKELY_OPENING_PUNCTUATION)
[duplication] ~143-~143: Possible typo: you repeated a word.
Context: ...irements:** - Valid SSL certificate on receiver - Receiver accessible from device ### Example Pay...
(ENGLISH_WORD_REPEAT_RULE)
🪛 markdownlint-cli2 (0.17.2)
README.md
54-54: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
55-55: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
🔇 Additional comments (6)
app/src/main/java/app/callgate/android/App.kt (3)
5-11: Import statements have been updated to support new webhook functionality.The new imports reflect the architectural changes - adding database support through
dbModule, orchestration capabilities viaOrchestratorServiceandorchestratorModule, and webhook functionality withwebhooksModule. These imports align well with the PR objective of adding webhook support.
25-32: Module registration has been properly updated in the Koin DI setup.The new modules (
dbModule,webhooksModule, andorchestratorModule) have been added to the Koin initialization in a logical order. This ensures that all the dependencies required for webhook functionality are properly registered in the application's dependency injection system.
35-35:Details
✅ Verification successful
Service initialization approach has been refactored.
The previous conditional initialization using
GeneralSettingsandServerServicehas been replaced with a direct and unconditional start of theOrchestratorService. Thetrueparameter likely indicates auto-start behavior.
🌐 Web query:
What is the purpose of an OrchestratorService in Android?💡 Result:
In Android, the purpose of an OrchestratorService typically refers to its role in managing and coordinating processes or components, ensuring modular, scalable, and efficient execution. Below are its specific uses in common contexts:
1. Android Test Orchestrator
The Android Test Orchestrator is a tool designed for automated testing in Android applications. It ensures that each test runs independently in its own
Instrumentationinstance, isolating tests to reduce shared state and potential conflicts. Key benefits include:
- Minimizing shared state: Tests run in isolation, and shared application state is cleared after each test using the
clearPackageDataflag.- Handling crashes effectively: If a test crashes, it only affects its instance, allowing other tests to proceed uninterrupted.
- Reducing Out of Memory (OOM) issues: By clearing memory after each test, the orchestrator prevents memory leaks and improves reliability for large test suites[1][5][9].
To achieve this, the
OrchestratorServicemay implement mechanisms to manage these isolated test instances.2. General Orchestration in Android Components
In broader terms, an OrchestratorService in Android might also be used to coordinate interactions between different components (e.g., services, activities, or APIs). For example:
- It can act as a central controller, similar to an event manager, directing actions between various components to achieve a unified workflow.
- It might handle the setup, communication, or teardown of resources required to streamline tasks, ensuring they run in an orderly manner with minimal conflicts[2].
3. Microservices or App Architecture
In some cases, the OrchestratorService is applied to coordinate different microservices or modules in a complex application. This aligns with orchestration philosophies that manage dependencies, service discovery, or data exchanges efficiently, ensuring cohesive execution of diverse processes.
Applications
- Testing: As highlighted with the Android Test Orchestrator, it’s particularly useful in maintaining large-scale test scenarios.
- Workflow Management: For apps requiring coordination of multiple backend tasks or client-server interactions.
Thus, the OrchestratorService in Android plays a vital role in optimizing and orchestrating workflows, whether for testing, application architecture, or service coordination. Its design ensures modularity, reliability, and streamlined operations.
Citations:
- 1: https://developer.android.com/training/testing/instrumented-tests/androidx-test-libraries/runner
- 2: https://www.onespan.com/blog/authenticator-activation-on-android-studio
- 3: https://www.uipath.com/product/orchestrator
- 4: https://docs.omnissa.com/bundle/Freestyle-Orchestrator-guideVSaaS/page/freestyle-orchestrator.html
- 5: https://tudip.com/blog-post/implementation-of-android-test-orchestrator/
- 6: https://github.com/android/android-test/blob/master/runner/android_test_orchestrator/java/androidx/test/orchestrator/AndroidTestOrchestrator.java
- 7: https://learn.ocp.ai/guides/what-is-orchestrator
- 8: https://www.juniper.net/documentation/us/en/software/juniper-paragon-automation2.1.0/user-guide/topics/concept/service-orchestration-overview.html
- 9: https://firebase.google.com/docs/test-lab/android/instrumentation-test
- 10: https://www.advsyscon.com/blog/service-orchestration-what-is/
OrchestratorService Initialization Refactoring – Approved
The refactored initialization now directly calls
OrchestratorService.start(this, true), which aligns with its role in managing and coordinating processes. Thetrueparameter clearly indicates auto-start behavior, and based on our verification, this approach simplifies the initialization by removing the previous conditional checks involvingGeneralSettingsandServerService.
- File:
app/src/main/java/app/callgate/android/App.kt(Line 35)- Observation: The unconditional initialization using
get<OrchestratorService>().start(this, true)is appropriate given the orchestrating responsibilities of the service in both test and production workflows.All concerns have been addressed.
README.md (1)
143-143: Verify repeated wording.The line mentions "receiver" twice. Validate whether any repetition is unintentional or inaccurate. If the repetition is required, feel free to ignore this warning.
🧰 Tools
🪛 LanguageTool
[duplication] ~143-~143: Possible typo: you repeated a word.
Context: ...irements:** - Valid SSL certificate on receiver - Receiver accessible from device ### Example Pay...(ENGLISH_WORD_REPEAT_RULE)
app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt (1)
150-151: Reuse a shared HttpClient or confirm ephemeral usage.Closing and recreating an HttpClient in each worker may cause performance overhead if webhooks are frequent. Confirm if ephemeral usage is intentional or consider injecting a shared HttpClient to preserve resources.
app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt (1)
56-60: Confirm local host exception approach.This check allows
http://127.0.0.1but disallows other local IPs (e.g., 192.168.x.x). Ensure this restriction is intentional. If not, broaden local host acceptance.
23f77de to
b2cc7d7
Compare
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: 0
🧹 Nitpick comments (2)
README.md (2)
55-99: API usage examples are clear and accurate, but minor markdown and formatting improvements are possible.
- The curl examples and endpoint documentation are well-aligned with the described API.
- The static analysis tool flagged "Loose punctuation mark" at lines 77 and 96, likely due to the use of bolded "Responses:" and "Responses" as pseudo-headings. Consider using proper markdown headings for these sections for better accessibility and markdownlint compliance.
Example improvement:
-**Responses:** +#### Responsesand
-**Responses** +#### ResponsesThis will also resolve the markdownlint MD036 warning.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~77-~77: Loose punctuation mark.
Context: ...v1/calls ``` Responses: -200 OK: Call initiated - `400 Bad Request`: Inv...(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~96-~96: Loose punctuation mark.
Context: ...s ``` Responses -204 No Content: Call ended - `404 Not Found`: No ringin...(UNLIKELY_OPENING_PUNCTUATION)
🪛 markdownlint-cli2 (0.17.2)
94-94: Emphasis used instead of a heading
null(MD036, no-emphasis-as-heading)
100-166: Webhook system documentation is comprehensive and technically accurate.
- The events, configuration endpoints, and example payloads are clearly described and match the implementation.
- The compatibility notes with SMSGate and the requirements for SSL and accessibility are well-stated.
- Static analysis flagged a possible repeated word at line 141 ("on receiver - Receiver accessible..."). This is not a true repetition but could be clarified for style:
Example improvement:
-- Valid SSL certificate on receiver -- Receiver accessible from device +- Valid SSL certificate on the webhook receiver +- Webhook receiver must be accessible from the device🧰 Tools
🪛 LanguageTool
[duplication] ~141-~141: Possible typo: you repeated a word.
Context: ...irements:** - Valid SSL certificate on receiver - Receiver accessible from device ### Example Pay...(ENGLISH_WORD_REPEAT_RULE)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (52)
README.md(1 hunks)app/build.gradle.kts(4 hunks)app/schemas/app.callgate.android.modules.db.AppDatabase/1.json(1 hunks)app/src/main/AndroidManifest.xml(1 hunks)app/src/main/java/app/callgate/android/App.kt(2 hunks)app/src/main/java/app/callgate/android/domain/EntitySource.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/CallsService.kt(3 hunks)app/src/main/java/app/callgate/android/modules/calls/events/CallEvent.kt(1 hunks)app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/Converters.kt(1 hunks)app/src/main/java/app/callgate/android/modules/db/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/notifications/NotificationsService.kt(2 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/ServerService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt(2 hunks)app/src/main/java/app/callgate/android/modules/server/WebService.kt(6 hunks)app/src/main/java/app/callgate/android/modules/server/routes/CallsRoutes.kt(2 hunks)app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt(1 hunks)app/src/main/java/app/callgate/android/modules/settings/Module.kt(2 hunks)app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/Module.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHook.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookDTO.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEvent.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEventDTO.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt(1 hunks)app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt(1 hunks)app/src/main/java/app/callgate/android/ui/HomeFragment.kt(5 hunks)app/src/main/java/app/callgate/android/ui/settings/BasePreferenceFragment.kt(2 hunks)app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt(1 hunks)app/src/main/res/drawable-notnight/ic_no_internet.xml(1 hunks)app/src/main/res/drawable-notnight/ic_retry.xml(1 hunks)app/src/main/res/drawable-notnight/ic_signing_key.xml(1 hunks)app/src/main/res/drawable-notnight/ic_webhook.xml(1 hunks)app/src/main/res/drawable/ic_no_internet.xml(1 hunks)app/src/main/res/drawable/ic_retry.xml(1 hunks)app/src/main/res/drawable/ic_signing_key.xml(1 hunks)app/src/main/res/drawable/ic_webhook.xml(1 hunks)app/src/main/res/drawable/notif_server.xml(1 hunks)app/src/main/res/drawable/notif_webhook.xml(1 hunks)app/src/main/res/values/strings.xml(1 hunks)app/src/main/res/xml/root_preferences.xml(1 hunks)app/src/main/res/xml/webhooks_preferences.xml(1 hunks)build.gradle.kts(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- app/src/main/java/app/callgate/android/modules/webhooks/WebhooksSettings.kt
- app/src/main/java/app/callgate/android/modules/server/routes/WebhooksRoutes.kt
- app/src/main/res/values/strings.xml
🚧 Files skipped from review as they are similar to previous changes (48)
- app/src/main/java/app/callgate/android/domain/EntitySource.kt
- app/src/main/java/app/callgate/android/modules/calls/webhooks/CallEventPayload.kt
- app/src/main/res/drawable/ic_retry.xml
- app/src/main/res/drawable-notnight/ic_no_internet.xml
- app/src/main/java/app/callgate/android/modules/webhooks/Module.kt
- app/src/main/res/drawable-notnight/ic_signing_key.xml
- app/src/main/java/app/callgate/android/ui/settings/BasePreferenceFragment.kt
- app/src/main/java/app/callgate/android/modules/db/Module.kt
- app/src/main/AndroidManifest.xml
- app/src/main/res/drawable/ic_signing_key.xml
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookDTO.kt
- app/src/main/res/drawable-notnight/ic_retry.xml
- app/src/main/java/app/callgate/android/modules/server/routes/CallsRoutes.kt
- app/src/main/res/drawable/ic_webhook.xml
- app/src/main/res/drawable/notif_webhook.xml
- app/src/main/java/app/callgate/android/modules/server/WebService.kt
- app/src/main/java/app/callgate/android/modules/orchestrator/Module.kt
- app/src/main/res/drawable/ic_no_internet.xml
- app/src/main/res/drawable-notnight/ic_webhook.xml
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEventDTO.kt
- app/src/main/java/app/callgate/android/modules/server/ServerSettings.kt
- app/src/main/java/app/callgate/android/modules/settings/Module.kt
- app/src/main/java/app/callgate/android/modules/webhooks/db/WebHook.kt
- app/src/main/java/app/callgate/android/modules/settings/PreferencesStorage.kt
- app/schemas/app.callgate.android.modules.db.AppDatabase/1.json
- build.gradle.kts
- app/src/main/res/drawable/notif_server.xml
- app/src/main/java/app/callgate/android/ui/settings/WebhooksSettingsFragment.kt
- app/src/main/java/app/callgate/android/App.kt
- app/src/main/java/app/callgate/android/modules/server/ServerService.kt
- app/src/main/java/app/callgate/android/modules/webhooks/domain/WebHookEvent.kt
- app/src/main/java/app/callgate/android/modules/notifications/NotificationsService.kt
- app/src/main/java/app/callgate/android/modules/server/Module.kt
- app/src/main/java/app/callgate/android/modules/calls/events/CallEvent.kt
- app/src/main/java/app/callgate/android/modules/calls/CallsService.kt
- app/src/main/java/app/callgate/android/modules/db/AppDatabase.kt
- app/src/main/java/app/callgate/android/modules/webhooks/plugins/PayloadSigningPlugin.kt
- app/src/main/res/xml/root_preferences.xml
- app/src/main/java/app/callgate/android/modules/webhooks/TemporaryStorage.kt
- app/src/main/java/app/callgate/android/modules/webhooks/db/WebHooksDao.kt
- app/src/main/java/app/callgate/android/modules/calls/CallsReceiver.kt
- app/src/main/java/app/callgate/android/modules/orchestrator/OrchestratorService.kt
- app/src/main/java/app/callgate/android/ui/HomeFragment.kt
- app/src/main/java/app/callgate/android/modules/db/Converters.kt
- app/build.gradle.kts
- app/src/main/java/app/callgate/android/modules/webhooks/WebHooksService.kt
- app/src/main/java/app/callgate/android/modules/webhooks/workers/SendWebhookWorker.kt
- app/src/main/res/xml/webhooks_preferences.xml
🧰 Additional context used
🪛 LanguageTool
README.md
[uncategorized] ~77-~77: Loose punctuation mark.
Context: ...v1/calls ``` Responses: - 200 OK: Call initiated - `400 Bad Request`: Inv...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~96-~96: Loose punctuation mark.
Context: ...s ``` Responses - 204 No Content: Call ended - `404 Not Found`: No ringin...
(UNLIKELY_OPENING_PUNCTUATION)
[duplication] ~141-~141: Possible typo: you repeated a word.
Context: ...irements:** - Valid SSL certificate on receiver - Receiver accessible from device ### Example Pay...
(ENGLISH_WORD_REPEAT_RULE)
🪛 markdownlint-cli2 (0.17.2)
README.md
94-94: Emphasis used instead of a heading
null
(MD036, no-emphasis-as-heading)
🔇 Additional comments (5)
README.md (5)
10-29: Excellent documentation structure and clarity.The expanded table of contents and features section provide a clear overview of the app's capabilities and organization. This will help users quickly find relevant information.
39-54: Clear and actionable getting started instructions.The explicit instruction to change the default password is a good security practice. The step-by-step installation and setup process is easy to follow.
167-172: Security best practices are well-presented.The dedicated section for security is a good addition, emphasizing credential rotation, network restrictions, and encryption.
173-177: Related projects section is clear and helpful.The update to describe SMSGate as a complete SMS management solution and the link to its repository provide valuable context for users.
180-184: Project status and version warning are clear and appropriate.Explicitly stating that the app is in active development and not production-ready sets correct expectations for users.
Summary by CodeRabbit
New Features
WebhooksSettingsFragment.CallsReceiverand refined call event processing.SendWebhookWorker.Refactor
Chore