Loading components
Send and receive iMessage, RCS, and SMS in Convex actions with signed webhook verification, idempotent sends, and zero component-owned storage.
npm install @linqapp/convexLinq Messaging connects your Convex backend to iMessage, RCS, and SMS through the Linq Partner API. Verify inbound webhooks, reply in an existing conversation, or start a conversation with an explicit sender line or automatic line selection. Read receipts, typing indicators, and delivery events use the same integration.
The component runs in Convex’s default runtime and does not create message tables or scheduled jobs. Your app controls its own conversation state, agent behavior, and retention. A complete example covers installation, webhook registration, replies, and outbound sends.
The @linqapp/convex component registers an HTTP route at /linq/webhook that verifies Standard Webhooks signatures and calls your configured onMessage action. You define the handler as an internalAction using the onMessageArgs schema, and the component passes verified message fields like chatId, from, text, and messageId directly to your handler.
Call linq.sendMessage from any Convex action with a chatId or a to phone number array, message text, and a stable idempotencyKey. The component retries on network errors and transient failures using the same key, so duplicate calls with the same key will not send the message twice.
Configure the Linq component with an onMessage handler action that receives inbound messages, calls your LLM, and replies using linq.sendMessage with an idempotencyKey derived from the inbound messageId. For slow LLM calls that exceed the 10-second webhook deadline, use ctx.scheduler.runAfter to defer the work and pass message identifiers rather than full text on zero-retention lines.
The @linqapp/convex component lets you supply a stable idempotencyKey to linq.sendMessage. Linq enforces that each key is sent at most once, so if a webhook is redelivered and your handler runs again, the same key prevents a duplicate outbound message. If you omit the key, the component generates a random one that only protects the in-call retries of that single invocation.
No. The @linqapp/convex component declares no database tables and schedules no background jobs. Inbound message data exists only in memory during the webhook request and in the arguments of your onMessage action. Any persistence is entirely your responsibility in your own application tables.
If your onMessage handler throws or the response is not returned within 10 seconds, the component returns HTTP 500 and Linq redelivers the event, retrying for up to 30 minutes. You should make all handler side effects safe to repeat and derive idempotencyKey from the inbound messageId so that a redelivery does not send a duplicate reply.
No. The Linq Convex component runs in Convex's default runtime and does not require the 'use node' directive on any of its functions.
Use ctx.scheduler.runAfter inside your onMessage handler to schedule the slow work as a separate Convex action. This returns control to the webhook immediately. On zero-day-retention lines, pass only message identifiers to the scheduled action rather than full message text, since scheduled job arguments persist in your Convex deployment for 7 days after the job finishes.
The @linqapp/convex component verifies Standard Webhooks signatures on every inbound request using the LINQ_WEBHOOK_SECRET environment variable before your handler is called. An invalid or missing signature returns HTTP 401 and no handler runs. A missing or misconfigured local secret returns HTTP 500 so Linq can redeliver after you fix the deployment configuration.