Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Dec 11, 2025

Summary

Adds a Slack Events API webhook endpoint that listens for Loops bot messages about new contacts and automatically threads a reply with the contact's status and source information. When Loops posts a message like <mailto:[email protected]|[email protected]> was added to your account, this webhook extracts the email, looks up the contact in Loops, classifies their status, and replies in a thread with Status: {status} (Source: {source}, Intent: {intent}, Platform: {platform}).

Contact Status Classification:

  • paid — Source = "Stripe webhook"
  • signed up — Source = "Supabase webhook"
  • interested — Source = "LANDING_PAGE" + Intent = "Waitlist" + Platform = "Windows" or "Linux"
  • unknown — anything else

New files:

  • apps/api/src/middleware/slack.ts - Slack signature verification middleware
  • apps/api/src/integration/loops.ts - Loops API client + classifyContactStatus function
  • apps/api/src/integration/slack.ts - Slack API client to post thread replies

New environment variables (all optional):

  • SLACK_BOT_TOKEN - Bot token for posting messages
  • SLACK_SIGNING_SECRET - For webhook signature verification
  • LOOPS_API_KEY - For fetching contact data
  • LOOPS_SLACK_CHANNEL_ID - Optional channel filter

Review & Testing Checklist for Human

  • Verify status classification strings match exactly - The classification uses exact string matching for "Stripe webhook", "Supabase webhook", "LANDING_PAGE", "Waitlist", "Windows", "Linux". Confirm these match the actual values stored in Loops (case-sensitive).
  • Verify Loops API returns intent and platform as top-level fields - I assumed these are top-level fields on the contact object. They might be custom fields with different names in the actual API response.
  • Verify Slack signature verification logic - The HMAC-SHA256 implementation in middleware/slack.ts was written manually using Web Crypto API. Compare against Slack's official documentation.
  • Test email extraction regex - The regex /<mailto:([^|]+)\|/ should match the actual Loops message format. Test with real messages.
  • Consider idempotency - If Slack retries the webhook, duplicate thread replies could be posted. May want to add deduplication logic.

Recommended test plan:

  1. Deploy to staging with all env vars configured
  2. Configure Slack app with Event Subscriptions pointing to {API_URL}/webhook/slack/events
  3. Subscribe to message.channels events
  4. Add test contacts in Loops with different Source/Intent/Platform combinations
  5. Verify the thread replies show correct status classification for each case

Notes

  • The webhook handles Slack's url_verification challenge for initial setup
  • Messages are filtered to only process bot messages containing "was added to your account"
  • Errors are captured in Sentry with relevant context
  • Thread reply format: Status: {status} (Source: {source}, Intent: {intent}, Platform: {platform})

Link to Devin run: https://app.devin.ai/sessions/c9e80737c4dc4ebda4eed2f6c217928c
Requested by: [email protected] (@ComputelessComputer)

- Add Slack Events API webhook endpoint at /webhook/slack/events
- Extract email from Loops bot messages and look up contact Source
- Post threaded reply with Source field under Loops bot messages
- Add Slack signature verification middleware
- Add Loops API integration to fetch contact by email
- Add environment variables: SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET, LOOPS_API_KEY, LOOPS_SLACK_CHANNEL_ID

Co-Authored-By: [email protected] <[email protected]>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@netlify
Copy link

netlify bot commented Dec 11, 2025

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit 608e2bd
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/693afa7b169fe800086128de
😎 Deploy Preview https://deploy-preview-2222--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Dec 11, 2025

Deploy Preview for hyprnote-storybook ready!

Name Link
🔨 Latest commit 608e2bd
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/693afa7b7463b000084c520e
😎 Deploy Preview https://deploy-preview-2222--hyprnote-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Comment @coderabbitai help to get the list of available commands and usage tips.

devin-ai-integration bot and others added 3 commits December 11, 2025 16:50
- Improve email regex to handle + and other valid characters
- Add timeout to Slack API requests with AbortController
- Handle Slack API errors properly (check ok: false in JSON response)
- Export LoopsContact interface

Co-Authored-By: [email protected] <[email protected]>
- Add classifyContactStatus function to categorize contacts based on Source, Intent, Platform
- Paid: Source = 'Stripe webhook'
- Signed up: Source = 'Supabase webhook'
- Interested: Source = 'LANDING_PAGE' + Intent = 'Waitlist' + Platform = 'Windows' or 'Linux'
- Update Slack thread reply to show status with details

Co-Authored-By: [email protected] <[email protected]>
@devin-ai-integration devin-ai-integration bot changed the title feat: add Slack webhook to thread Loops contact Source field feat: add Slack webhook to thread Loops contact status and source Dec 11, 2025
@ComputelessComputer ComputelessComputer merged commit e275f0f into main Dec 11, 2025
13 of 14 checks passed
@ComputelessComputer ComputelessComputer deleted the devin/1765471188-loops-source-slack-thread branch December 11, 2025 17:19
@devin-ai-integration devin-ai-integration bot mentioned this pull request Dec 11, 2025
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants