laravel-notification-channels/todoist
Laravel notification channel for Todoist, letting you send notifications that create tasks in a Todoist project. Configure the channel and route notifications to your users so alerts, reminders, and app events become actionable Todoist items.
Architecture fit — good on paper, irrelevant in practice. A Laravel notification channel is one of the cleanest extension points in the framework: via() returns a channel string, the channel class implements send(), and a service provider binds it in the container. It touches no schema, replaces no core, and sits behind one seam in the notification pipeline. Architecturally, this is the ideal kind of package to adopt — shallow, replaceable, framework-conventional. The problem is not the pattern; it is the artifact.
Integration feasibility — effectively zero as a direct dependency. Signals that block a straight composer require:
illuminate/support to the 5.x line and PHP to the 5.6/7.0 era. On any modern Laravel (9/10/11/12) the solver will refuse; composer why-not will confirm in minutes.Technical risk — high, and mostly known rather than unknown. Abandonment is declared, not latent. There is no security disclosure channel, no CVE response path, no upgrade cadence, and nobody to ask when a Todoist API change lands mid-quarter. The blast radius is contained (outbound notifications only, no schema, no auth, no data ownership) — which is the one favorable property. It means the risk is exit cost, not data lock-in.
Key questions before any further work
Bottom line for the TPM: this is not a dependency to adopt — it is a reference implementation and a template for a ~150–300 line in-house channel. The correct decision it supports is "build, don't buy, and use this repo to de-risk the estimate."
Stack fit — assume incompatibility until proven otherwise. Verify against the actual estate: PHP version, Laravel major, queue driver, HTTP client already in the tree (Guzzle vs. Laravel Http facade). A 2016 package will predate Http:: entirely. Do not schedule a sprint until composer why-not has been run against every target app's lockfile.
Migration path — there is none to inherit. No 0.x → 1.0 lineage matters here; there is no prior assessment, no adoption register, and no known informal usage to reconcile. The path is greenfield regardless:
toTodoist() payload). This is the entire value transfer.TodoistChannel::send(), a Todoist service provider, a publishable config, and an Http-facade client against the current Todoist API. Add idempotency (dedupe key per notification) and explicit 401/429 handling.Http::fake()-based unit tests covering success, 401, 429, and malformed payload.Compatibility — the solver is the arbiter. Confirm the package cannot coexist with the current framework before assuming a fork is cheaper than a rebuild. In practice, a fork means: rewrite composer.json constraints, modernize the HTTP layer, and then own an orphaned repo — which is strictly worse than owning 200 lines in your own tree.
Sequencing — decision gate first.
Maintenance — if you adopt, you are the maintainer. "Archived" is the project's own statement that nobody is triaging issues, merging PRs, or cutting releases. The TCO delta versus a healthy dependency is the entire support function: no upstream fixes, no security patches, no upgrade guidance.
Support — none. No issue response, no advisory channel, no maintainer to escalate to when Todoist changes an endpoint. Any production incident is yours to diagnose with no upstream.
Scaling — bounded by a third party. Throughput is gated by Todoist's per-user API rate limits, not by your application. Two operational requirements follow:
Failure modes to instrument
| Mode | Signal | Mitigation in-house build |
|---|---|---|
| Token expired / rotated | 401 | Explicit error, alert on N consecutive failures |
| Rate limited | 429 / backoff | Honor Retry-After, exponential backoff, cap retries |
| Duplicate tasks on retry | User complaint | Idempotency key per notification instance |
| Silent drop | Missing tasks, no logs | Log every failure at warning, metric on send rate |
| API contract change | Sudden 400s | Contract test against Todoist sandbox in CI |
Ramp-up — the one genuinely favorable line item. The integration surface is tiny. An engineer can read the whole package in an hour and reproduce it in a day. That low ramp-up is precisely why the package's highest-value use is as a specification, not a dependency — it lets you estimate and de-risk the in-house build with near-certainty, then hand ownership to a named engineer on your own team.
Recommendation: do not add this as a dependency. Use the repository as a reference for a 1–2 engineer-day in-house notification channel against the current Todoist API, assign a named owner, and treat the whole exercise as a roadmap item closed in one sprint rather than a permanent external dependency. Revisit only if a maintained, actively-released fork appears with dependents and a security policy.
How can I help you explore Laravel packages today?