AI 资讯
Routing email into Slack, which is not the same as forwarding it
Every organisation that works in Slack still has email arriving somewhere else. Vendor notifications, form submissions, the address a partner replies to. The work is in one place and a meaningful slice of the information about it is in another, which someone checks when they remember. The obvious fix is forwarding. Point the mailbox at a Slack channel and let the integration post everything. It takes an afternoon, and it fails in a way that is worth describing precisely, because the failure is not "it did not work". It is that it worked exactly as specified and made things worse. What forwarding actually produces Truncated bodies. The integration posts a preview. The part of the email that says what to do is below the fold, so every message becomes a link to the thing you actually needed, and the channel is a table of contents for an inbox people are still opening. Reply chains, repeatedly. A thread with six replies does not arrive as one conversation. It arrives as six posts, each quoting all the previous ones, so the channel fills with the same text at increasing lengths. Auto-replies. Out-of-office, delivery receipts, no-reply confirmations. None of it is work and all of it arrives with the same weight as the message from a partner asking a real question. The predictable outcome is that the channel gets muted, and now the information is in two places neither of which anyone is reading. Routing, not forwarding The distinction that makes this work: a router decides what belongs in Slack and in what shape, rather than moving everything and hoping the reader filters. Concretely that means four things the forwarding integration does not do. Deduplication on the RFC Message-ID. Every email carries a globally unique Message-ID header, and replies carry In-Reply-To and References pointing back at what they answer. That is the correct identity for a message, rather than a hash of subject and sender, which collides on exactly the automated mail you receive most. The router
AI 资讯
The message that mentioned finance and tagged nobody
Somebody types "can we loop in finance on this?" in a product channel. Nobody tags the finance channel. The thread moves on. Three weeks later there is a contract nobody in finance has seen. That is not a tooling problem in any obvious sense. Slack worked exactly as designed. Search would have found the message if anyone had known to look for it. The failure is that the people who needed to know were never told, and nothing in the workspace was watching for the difference between mentioning a team and involving one. Why keyword matching does not solve this The instinct is to grep for the word "finance" and alert on it. That produces a channel nobody reads inside a week, because "finance" appears in sentences that have nothing to do with governance, and the sentences that do matter often do not contain the word at all. What actually carries the signal is structure. A Slack message is not plain text on the wire. When someone references a channel, it arrives looking like this: Can we loop in <#C01ABCDEF|finance> before this goes out? That is a channel reference , distinct from a mention that notifies the channel, and it survives in the event payload whether or not anyone was actually alerted. It means the workspace already knows the difference between "I said the word finance" and "I pointed at the finance channel and did not bring anyone in". Nobody was reading it. So the bot parses references rather than words. It maps channel IDs to what those channels are for, and it looks for the specific shape of a message that points at a governance channel from outside it. Context beats keywords, and in this case the context was already structured and already being thrown away. Two decisions that mattered more than the detection It joins every public channel by itself. The obvious build asks an admin to add the bot wherever it should watch, which means coverage is a function of somebody remembering. Every channel created after launch is a gap, and nobody finds out until somethi
AI 资讯
Adobe is making its tools available in Slack
Users will be able to access Express, Premiere, and Acrobat in Slack
AI 资讯
Email to Slack: threading, Block Kit limits, and the duplicate-post trap
Start from the mismatch, because every bug in this integration comes out of it. Email hands you a MIME tree, an SMTP envelope, and a Message-ID chain that defines the conversation. Slack hands you a channel, a message of at most 50 blocks, and a ts that defines the conversation. The whole job is mapping one onto the other without dropping information — the reply chain, the authentication verdicts, the attachments — on the floor. Here's the whole inbound half, as a Cloudflare Worker. It runs as pasted with one KV namespace bound as SEEN and one dependency ( npm install mailkite ): // worker.js — inbound email → Slack. wrangler secret put SLACK_BOT_TOKEN / MAILKITE_WEBHOOK_SECRET import { MailKite } from " mailkite " ; const clamp = ( s , n ) => ( s . length > n ? s . slice ( 0 , n - 1 ) + " … " : s ); function blocksFor ( email ) { const subject = email . subject || " (no subject) " ; const trusted = email . auth . dmarc === " pass " ; const sender = trusted && email . from . name ? ` ${ email . from . name } < ${ email . from . address } >` : email . from . address ; return [ { type : " header " , text : { type : " plain_text " , text : clamp ( `📧 ${ subject } ` , 150 ) } }, { type : " section " , fields : [ { type : " mrkdwn " , text : `*From:*\n ${ clamp ( sender , 2000 )}${ trusted ? "" : " ⚠️ " } ` }, { type : " mrkdwn " , text : `*To:*\n ${ email . to [ 0 ]. address } ` }, ] }, { type : " section " , text : { type : " mrkdwn " , text : clamp ( email . text || " _no text part_ " , 3000 ) } }, { type : " context " , elements : [ { type : " mrkdwn " , text : `spf \` ${ email . auth . spf ?? " unknown " } \` · dkim \` ${ email . auth . dkim ?? " unknown " } \` · dmarc \` ${ email . auth . dmarc ?? " unknown " } \` ` }, ] }, ]; } export default { async fetch ( req , env ) { const raw = await req . text (); const sig = req . headers . get ( " x-mailkite-signature " ); // HMAC recompute, constant-time compare, ±5-minute replay window: one call if ( ! MailKite . verify
AI 资讯
Building a Slack Approval Workflow That Deletes Cloud Infrastructure
Block Kit, signature verification, and the design decisions that stop a button click from becoming an incident. That screenshot is a bot asking permission to delete an EBS volume. Clicking Approve Remediation snapshots the volume, waits for the snapshot to complete, deletes the volume, and edits the message to say what happened. Getting that to work is mostly plumbing. Getting it to work safely , so that a stale click, a replayed request, or a resource someone protected in the meantime cannot cause damage, is the interesting part. This walks through both, using the Slack adapter from FinOps Sentinel . The shape of the problem Slack interactivity is two separate channels that only look like a conversation: Your app ──── incoming webhook ────▶ Slack channel │ user clicks │ Your app ◀─── HTTP POST ──────────────────┘ (a completely new request, from Slack's servers) The click arrives as an unauthenticated POST from the public internet to whatever URL you registered. Nothing about the request proves it came from Slack, or that a human clicked anything. That is the security problem in one sentence, and everything below follows from it. Part 1: Setting up the Slack app Create the app and get a webhook api.slack.com/apps → Create New App → From scratch Name it, pick your workspace Incoming Webhooks → toggle On → Add New Webhook to Workspace Choose a channel, click Allow , copy the URL SLACK_WEBHOOK_URL = https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX Webhooks post to exactly one channel and cannot read anything. For a notification bot that is the right amount of privilege: no OAuth flow, no bot token, no scopes to review. Enable interactivity Interactivity & Shortcuts → toggle On → set the Request URL: https://your-domain.example/callbacks/slack Locally you need a tunnel: ngrok http 8000 # → https://a1b2c3d4.ngrok.app # Request URL: https://a1b2c3d4.ngrok.app/callbacks/slack The free ngrok URL changes on every restart, and you must update Slack each time. Save your
AI 资讯
Building a Slack Deploy Queue Bot: Lessons from NestJS, BullMQ, and Redis in Production
Over the past few months I built a side project that taught me more about production system design than any course. A Slack bot for deploy queue management. This isn't about the business side of it, it's a technical breakdown of the architecture decisions, the real problems I hit building a Slack app with NestJS, and what I learned solving each one. The problem Every engineering team has lived this. Two people deploy at the same time, one overwrites the other, and it turns into "who's touching prod right now?" shouted into a Slack channel. Sounds simple. Solving it properly across multiple teams, multiple environments, with timeouts, without ever locking anyone out, is not. Stack and why NestJS + TypeScript on the backend, PostgreSQL via Prisma, Redis + BullMQ for background jobs, @slack/bolt for the Slack integration. Choosing NestJS wasn't just preference. Its modular architecture (modules, providers, guards, interceptors) mapped really well to the domain. Every entity (Workspace, Project, Environment, Queue) became its own module, with the repository pattern keeping Prisma out of the business logic layer. The hardest problem: dynamic modals in Slack Block Kit Slack's Block Kit doesn't natively support a select input that reloads its options based on another select's value, within the same form. If you want "pick a project, then load that project's environments," there's no built-in prop for that. The solution combines two Bolt event types. A block_actions listener on the project select fetches the environments, then re-renders the whole modal via views.update : app . action ( ' project_select ' , async ({ ack , body , client }) => { await ack (); const selectedProjectId = body . actions [ 0 ]. selected_option . value ; const environments = await environmentService . findByProject ( selectedProjectId ); await client . views . update ({ view_id : body . view . id , view : buildModalWithEnvironments ( environments ), }); }); The detail that tripped me up the most: t
AI 资讯
Anthropic Shipped @Claude For Slack. My Team Runs On
Anthropic Shipped @claude for Slack. My Team Runs on Telegram. Anthropic just shipped @Claude inside Slack channels. Tag the bot, it reads the thread, does work async, posts back. Nice product. Except roughly 95% of small businesses don't live in Slack — they run on WhatsApp, Telegram, and Gmail. If you're a solopreneur or a 1-to-10-person team, here's the exact four-part recipe I use to run the same pattern in Telegram for under $12/month. What Anthropic actually shipped (and who it's for) Anthropic shipped an enterprise distribution deal wearing a product launch t-shirt. @Claude for Slack lets you tag the bot in a channel or thread, gives it channel memory, connects to your other apps, and returns work asynchronously — but only on Slack Team and Enterprise plans. That's the punchline: it lives where the annual contracts live. Look at the raw user counts. Slack's own reporting puts it around 35–40 million weekly active users globally. WhatsApp is over 2 billion. Telegram is over 900 million. Gmail sits around 1.8 billion. In the 1-to-10-employee segment outside US tech, Slack penetration is single digits. Small teams in Europe, LATAM, and most of Asia coordinate in WhatsApp groups and run pipeline out of Gmail. They are not about to add Slack seats at $15/user/month just to get an @Claude mention. That's a rational call for Anthropic — Slack is where the enterprise procurement motion already exists. It's just not a product for the operator segment. And the pattern they productized is trivially replicable on any messenger with a bot API. Platform Weekly/monthly active users Bot API Cost to run a mention-bot Slack ~35–40M WAU Yes, paid plan $15/user/mo + API Telegram ~900M MAU Yes, free ~$5–12/mo API only WhatsApp Business ~2B MAU Yes, metered $0.005–0.08/conversation + API Gmail ~1.8B MAU Pub/Sub push Free tier + API The four-part recipe (works in any messenger) Every mention-bot is the same four moving parts: a webhook that fires on mention, a context store that ho
AI 资讯
Slack Eliminates SSH in EMR Pipelines, Migrates 700+ Jobs to Rest-Based Architecture
Slack modernized its data platform by replacing SSH based execution in Amazon EMR pipelines with a REST driven orchestration layer called Quarry. The migration covered 700 plus Airflow operators, improving security, reliability, and observability while eliminating direct SSH access across production clusters and enabling a server side job lifecycle model. By Leela Kumili