今日已更新 240 条资讯 | 累计 23823 条内容
关于我们

标签:#api

找到 353 篇相关文章

AI 资讯

HollowGraph Malware Uses Microsoft 365 Calendar Events as Dead-Drop C2 Channel

What Happened On July 20, 2026, cybersecurity firm Group-IB disclosed a new espionage implant dubbed HollowGraph that hijacks compromised Microsoft 365 mailboxes to run a command-and-control (C2) channel hidden inside calendar events. The malware attaches encrypted files to calendar entries dated May 13, 2050 — far enough in the future that a mailbox owner would never scroll to them — and retrieves operator instructions from the same dead drop. All traffic moves through the Microsoft Graph API, making the activity indistinguishable from legitimate M365 usage. At least 12 systems have been infected, with three actively communicating with the threat actor between June 3 and July 9, 2026. The indicators point to a targeted espionage campaign focused on Israeli organizations . Technical Analysis HollowGraph is a lightweight .NET DLL that supports only two commands: GET and SEND . To receive tasking, it queries the compromised mailbox's calendar for an event titled in the format "Event ID: <7-char-taskID>", downloads the attached file, and decrypts it using RSA and AES-256-GCM. To exfiltrate data, the implant creates a new calendar entry titled "Boss{..}ID{..}" and uploads stolen files encrypted with the attacker's public RSA key. The Group-IB research team described the mailbox calendar as a "covert dead-drop," with HollowGraph retrieving commands from events scheduled within a fixed one-hour window between 22:00 and 23:00 UTC on the far-future date. The hybrid encryption scheme uses separate RSA key pairs for inbound and outbound channels, keeping them cryptographically isolated. A second, unencrypted channel runs over DNS tunneling . HollowGraph refreshes its Microsoft Entra ID (Azure AD) credentials by querying IPv6 AAAA records from the attacker-controlled domain cloudlanecdn[.]com . Each returned IPv6 address yields 14 usable payload bytes, which the malware assembles and decodes as UTF-8 text to update its logAzure.txt configuration file — a file masquerading as a

2026-07-21 原文 →
AI 资讯

How We Built an AI Document Fraud Detection Platform That Explains Every Decision

Why we built Veridexa Many document analysis workflows still rely primarily on OCR OCR is useful for extracting text, but it cannot answer one important question: Does this document show signs of fraud or manipulation? That question led us to build Veridexa. The problem Organizations receive thousands of digital documents every day: Passports National IDs Academic certificates Bank statements Employment documents Invoices Reading the text is only one part of the process. The difficult part is detecting manipulation, inconsistencies, forgery, or suspicious evidence before making a decision. Our approach Instead of relying on OCR alone, Veridexa combines multiple evidence sources into a single fraud assessment. The platform analyzes: OCR extraction Metadata Image forensics Security features Document structure Cross-evidence consistency The result is an explainable decision instead of a simple confidence score. Explainable decisions Every analysis ends with one of three outcomes: ACCEPT MANUAL REVIEW REJECT Each decision is accompanied by supporting evidence so reviewers understand why the system reached that conclusion. Public benchmark We also believe AI systems should be transparent. For that reason Veridexa publishes a public benchmark together with methodology and performance reporting instead of asking users to trust marketing claims. API-first Try the public demo, explore the benchmark, or integrate the API. Feedback from developers and security professionals is always welcome. https://veridexa.io Developers can integrate Veridexa into their own applications using our API while organizations can use the web platform without writing code. We'd love your feedback We're continuing to improve the platform and would genuinely appreciate feedback from the developer community. Website: https://veridexa.io

2026-07-20 原文 →
AI 资讯

Contact Form 7 Submitted Successfully, But Systeme CRM Never Received the Lead: A Practical API Debugging Guide

Your Contact Form 7 form can work perfectly from a user's perspective and still fail to deliver a lead to your CRM. The visitor fills out the form. The browser shows a success message. The WordPress form appears to have submitted correctly. But when you open Systeme CRM, the contact is nowhere to be found. This is one of the most confusing problems in form-to-CRM integrations because a successful form submission does not necessarily mean a successful API request. The complete workflow has multiple stages: Visitor ↓ Contact Form 7 ↓ WordPress ↓ API Request ↓ Systeme CRM ↓ Contact Record ↓ CRM Automation A failure at any stage can break the workflow. The key to debugging the integration is to stop treating the form submission as a single event and start checking each stage separately. First, separate the two different types of success There are two different questions: Did Contact Form 7 submit the form? This is a WordPress-side question. Did Systeme CRM accept and process the API request? This is an API and CRM-side question. These are not the same thing. A form can successfully collect: Name: John Doe Email: john@example.com Company: Example Inc. while the API request fails because: the endpoint is incorrect authentication is missing the request method is wrong the JSON payload is invalid the CRM expects different field names a required field is missing The first debugging step is therefore to identify exactly where the data flow stops. Step 1: Confirm that Contact Form 7 is collecting the expected data Start at the beginning. Look at the form fields: [text* your-name] [email* your-email] [tel your-phone] [text company] [textarea your-message] The important values are the actual field names: your-name your-email your-phone company your-message A common mistake is to assume that the visible label is the field name. For example: Visible label: Full Name Field name: your-name The integration needs the submitted field value associated with the actual field name. Before

2026-07-20 原文 →
AI 资讯

Stop writing a parser per site. Run five and let confidence decide.

For a long time I ran product extraction off a database of custom selector configs. Hundreds of retailers, each with its own set of CSS selectors mapped field by field: price here, title there, image over there. It worked. It was also a treadmill. Every retailer that redesigned its frontend silently broke its config, and the maintenance tax grew with every retailer I added. Hundreds of configs is hundreds of things that can rot without telling you, usually right before someone downstream asks why a brand's prices went null. At some point I stopped feeding it. The scraping platform I ran at my last engagement fed a 20M+ product catalogue at millions of pages a day, and the thing that made that survivable wasn't better per-site config. It was leaning on almost no per-site config at all. The pattern Instead of one careful parser per site, run several cheap generic extractors on every page, in parallel: JSON-LD. A huge share of e-commerce pages ship a schema.org/Product block because Google rewards it. It has name, price, currency, availability, images. It's the closest thing to a public API hiding in the HTML. OpenGraph tags. og:title , og:image , product:price:amount . Lower quality than JSON-LD, but present on sites too lazy for structured data, because everyone wants pretty link previews. Microdata / RDFa. Older sites, still surprisingly common outside the US. Embedded state. __NEXT_DATA__ , window.__INITIAL_STATE__ and friends. A JSON blob the site's own frontend hydrates from. Heuristics. A price-shaped string near a currency symbol inside the main content region. The largest above-the-fold image. The h1 . Dumb, and dumb works more often than you'd think. None of these is reliable alone. OG price tags go stale, JSON-LD sometimes describes the wrong variant, heuristics grab the crossed-out "was" price. The trick is you don't pick an extractor. You pick per field, and you let agreement between sources carry the decision. Confidence merge Each extractor emits candida

2026-07-20 原文 →
AI 资讯

digiutil.com - No install, no signup, no logs

Online file converters are one of those categories where the market leaders have gotten steadily worse. Signup walls, daily conversion caps, "premium" file size limits, upsell banners between you and your download. So when I found digiutil.com, I ran it against the usual suspects for the conversions I actually do. Here's how it stacks up. Where the incumbents lose you If you've used the big converter sites recently, you know the pattern: Account required before you can download your file, or after your first couple of conversions Daily limits on the free tier — often 1–2 files per day File size ceilings low enough that any real video file pushes you to a paid plan Ad-heavy pages where the actual convert button is the fifth-most-prominent thing on screen None of this is about the cost of conversion — it's funnel design. The product is deliberately inconvenient so you'll pay to make it convenient. What digiutil does differently No signup, period. Not "free account required," not "sign up to download." You drag a file in, it auto-detects the format, routes you to the right converter, and you get your file. That alone puts it ahead of most of the category for one-off conversions. No logs, per their policy. Most converter sites are vague about retention. digiutil's stated policy is no logs. Standard caveat still applies — anything you upload to any third-party service is a trust decision — but an explicit no-logs stance is more than most competitors offer. Broad format coverage in one place. Video, audio, images, PDFs, documents, data files, archives, fonts, and subtitles. With most alternatives you end up on a different site for each category (one for HEIC → JPG, another for subtitles, another for fonts), each with its own limits. Here it's one tool: MP4 → MP3, MOV → MP4, HEIC → JPG, DOCX → PDF, and the long tail. Compression too. Video, image, audio, and PDF compression alongside conversion — a task the dedicated compressor sites usually gate hardest behind paid tiers.

2026-07-20 原文 →
AI 资讯

How I Let an AI Agent Save a Draft on DEV

Reading a public website and changing something inside a signed-in account are not the same kind of job. I wanted an AI agent to collect the first 10 Hacker News stories, explain how it gathered them, and place that work inside my DEV editor. Save the article as a draft. Do not publish it. The hard part was not finding the stories. It was giving the agent enough access to finish inside my signed-in account without giving it permission to publish. That instruction contained two jobs with different access needs: Read public data from Hacker News. Change private account state by creating a draft in my signed-in DEV account. Using a full browser for the first job would add machinery and access that the result did not need. The public fetch path had neither the authenticated context nor the authority required for the second job. The useful question was not “Which browser tool should do everything?” It was “Where does this task actually cross into a browser?” Disclosure: I work on Unchained, SearchAgentSky, and Unbrowser. This article was prepared with AI assistance and reviewed before publication. The public step needed only fetch I initially opened Hacker News in a lightweight page session and queried its story links. It worked—but that did not mean it was necessary. Hacker News has a public API . The same result could be produced with ordinary HTTP: const base = " https://hacker-news.firebaseio.com/v0 " ; const ids = await fetch ( ` ${ base } /topstories.json` ). then ( r => r . json ()); const stories = await Promise . all ( ids . slice ( 0 , 10 ). map ( async ( id , index ) => { const story = await fetch ( ` ${ base } /item/ ${ id } .json` ). then ( r => r . json ()); return { rank : index + 1 , title : story . title , url : story . url ?? `https://news.ycombinator.com/item?id= ${ id } ` }; })); console . log ( JSON . stringify ( stories , null , 2 )); At 2026-07-19T03:19:04Z , the page query returned 30 Hacker News story anchors. At 2026-07-19T03:35:29.670Z , fetch

2026-07-19 原文 →
AI 资讯

Python quickstart: nutrition data in 10 lines

Python quickstart: nutrition data in 10 lines You can search Dietly's public nutrition catalog with one GET request to https://api.getdietly.com/search . The response is a JSON array of foods, not an object with a results property. Install requests , run the example below, and you have a working nutrition lookup. The rest of this page turns that single call into something dependable: a client class, correct field handling, and retries that respect the rate limit. Make your first request The only required parameter is q (minimum two characters). Use limit to cap results between 1 and 50. Ten is plenty while you explore. import requests r = requests . get ( " https://api.getdietly.com/search " , params = { " q " : " greek yogurt " , " limit " : 5 }, timeout = 10 ) r . raise_for_status () foods = r . json () for food in foods : print ( food [ " name " ], food . get ( " protein_g " )) Understand the fields you get back Each result is a flat object. Nutrient values are per 100 g of the product unless noted, and any nutrient can be null when the source label did not list it. Treat null as unknown, never as zero. Field Meaning id Stable Dietly food ID, used for direct lookups name , brand Product name and brand when known calories_kcal Energy per 100 g protein_g , fat_g , carbs_g Macronutrients per 100 g fiber_g , sugar_g , saturated_fat_g , sodium_mg Detail nutrients per 100 g, often null serving_size_g , serving_desc One serving in grams and its label wording, when provided source , confidence Where the record came from and how sure Dietly is static_url Path to the food's page on getdietly.com, when one exists To convert a per-100 g value to a portion, multiply by grams and divide by 100. For a 150 g serving of a food with 10 g protein per 100 g, that is 10 * 150 / 100 = 15 g. Read the result defensively An empty search is [] , which is a normal outcome rather than an error. Guard for it, and keep null nutrients as null in your own model. food = foods [ 0 ] if foods else

2026-07-19 原文 →
AI 资讯

x402 processed 169M payments. On my eight MCP servers: zero. Only the scouts arrived.

Part of a series on building cz-agents → under the hood. Where we left off In June, I compared the three camps of agentic payments here—x402, card tokens, and banks—and argued that x402 will take machine-to-machine micropayments, while cards and banks split the rest. I won't repeat the basics of the protocol, how the 402 status code works, or why cards don't add up economically on tiny amounts; anyone who needs a refresher will find it in that article. This piece is about something else. A few weeks have passed; the numbers and the big-player backing have both jumped by an order of magnitude, and for the first time, I can compare those figures against what I actually see in my own logs. The gap between the two is the entire point of what follows. The numbers are hard to miss I'll start with what speaks for x402, because that's the more honest approach. According to aggregate Chainalysis data, the protocol has processed over 169 million payments so far, between roughly 590,000 buyers and 100,000 sellers. That's no longer a conference demo. More interesting than the volume is the structural shift. The share of transactions above one dollar rose from 49% in early 2025 to roughly 95% in early 2026. In other words: x402 is ceasing to be a toy for micro-cents and is starting to handle amounts that actually show up on the books. Anyone who wrote the protocol off as a curiosity for paying fractions of a cent per API query is looking at an old snapshot. Above all, a lineup has assembled that is hard to dismiss as crypto-bubble enthusiasts: Stripe launched x402 support on February 10, 2026, in the preview of its Machine Payments product (USDC on the Base network). Ripple added native x402 to the XRP Ledger on June 21, 2026. AWS built x402 into Bedrock AgentCore Payments—together with Coinbase and Stripe—and also lets you monetize agent traffic on CloudFront and WAF. Sites behind Amazon's edge can charge agents right at the edge, without touching their core application. Google

2026-07-19 原文 →
AI 资讯

Google custom search api free limit: How to bypass the cap

Running out of API quota in the middle of a production deployment is a frustrating rite of passage. If you are using the Google Custom Search API, you have likely hit that 100 free daily queries wall. Once you do, your application throws a 403 Quota Exceeded error, stalling your features unless you link a billing card and risk uncapped charges of $5 per 1,000 queries. In my experience, relying on Google's default limits without safeguards is a major liability. Here is how I protect my cloud budget, stretch the free tier using Redis, and transition to scalable alternatives when 100 queries are no longer enough. Step 1: Enforce a Hard Billing Cap in GCP Never rely on email alerts alone; they do not stop API requests. If a recursive loop in your code or a malicious bot targets your search endpoint, your credit card will bear the brunt. To set up a hard stop: Log into your Google Cloud Console . Navigate to APIs & Services > Enabled APIs & Services . Select Custom Search API , then click the Quotas tab. Locate Queries per day and click the edit pencil icon. Set your maximum limit to 95 (not 100). Pro Tip: This 5-query cushion gives you a safe buffer for emergency local debugging without triggering paid overages. Step 2: Implement Redis Caching Middleware Over 40% of search queries in typical web applications are repetitive. Implementing a Redis database to cache these searches can cut your API consumption by up to 80%. Here is a simple Python middleware pattern to normalize queries and cache them with a 24-hour Time-To-Live (TTL): import redis import requests # Connect to local Redis instance cache = redis . Redis ( host = ' localhost ' , port = 6379 , db = 0 , decode_responses = True ) def fetch_search_results ( query , api_key , search_engine_id ): # Normalize input to avoid duplicate cache keys normalized_query = query . strip (). lower () cache_key = f " search:cache: { normalized_query } " # 1. Check local cache first cached_data = cache . get ( cache_key ) if cach

2026-07-19 原文 →
AI 资讯

Trust the Calculator

The pricing formulas in Motor, the estimating engine I built for a water feature shop, did not come from the manual. I pulled 32 of them out of the JavaScript behind Aquascape's contractor calculator, the tool contractors actually use to bid jobs. The manual was sitting right there, official and free. Ignoring it was the best design decision in the whole system. A vendor never ships a sloppy calculator Why trust the calculator over the manual? Because of what happens when each one is wrong. If the manual sizes a pump wrong, a reader shrugs and moves on. If the calculator sizes a pump wrong, a contractor bids a job at that number, wins it, and loses money on the install. Then the phone rings. So calculators get fixed and manuals drift. Give it ten years and the two quietly disagree, and everyone in the trade knows which one to trust without anyone saying so. A vendor will ship a sloppy PDF. They will never ship a sloppy calculator. Documentation is what a domain says about itself. The artifacts money flows through are what it actually believes. Once you see that split, you cannot stop seeing it. The other half was in old invoices Formulas only get you to cost. What a shop charges on top of cost is a belief about its market, and no vendor document holds that number. So I pulled 132 historical quotes out of the shop's CRM. Real quotes, sent to real customers, most of them paid. I calibrated Motor's markup against those, then checked its output against what the shop had actually charged. The result: Calibrated against 132 real quotes, Motor's estimates landed within 5 percent of what the shop actually charged, with no pricing rule taken from documentation. I could have just asked the owner what his markup was. But what an owner says and what his invoices show are rarely the same number, and the invoices are the ones customers paid. When the two disagree, believe the invoices. The same bug in a different industry I build and run systems in several industries, and the sur

2026-07-19 原文 →
AI 资讯

Investor Database API: Filter 10,469 VC, Angel, and PE Firms as JSON in 2026

Every founder I know has burned a week building an investor list: digging through Crunchbase profiles tab by tab, copying partner names into a spreadsheet that is stale before the seed round closes. The data you want is simple, firms plus focus plus contacts, and it is weirdly hard to get in bulk. The shortcut I use now is the Startup Investors Data Scraper on Apify, a queryable investor database of 10,469 firms that returns filtered JSON in one call. Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you. Is there a public API for investor data? Not really. The big commercial databases keep their APIs behind sales calls and paid plans sized for funds, not founders. Free sources are scattered lists and shared spreadsheets with no filters and no freshness guarantees. This Actor takes a different shape: a curated database of 10,469 investment firms (as of December 2025) that you query like an API, filtering by firm type, sector, stage, and country, and paying only for the records you pull. What the investor database API returns The investor database API returns one JSON record per firm: name, type, description, location, website, social links, assets under management, stages, and sector focus, with partner contacts when you ask for them. Field Example Notes firm_name Acme Ventures With firm_description alongside firm_type_name Venture Capital Investor One of 17 firm types firm_country Germany Plus firm_city and firm_state firm_website https://acme.vc Also firm_linkedin_url , crunchbase_url , twitter_url firm_aum $250M Assets under management when known investor_contacts [{ "job_title": "Partner", ... }] Names, titles, LinkedIn URLs, emails when available, and check sizes, with Include_Contacts on Who this is for Founders building a raise pipeline, sales teams selling into VC and PE back offices, and analysts mapping which firms fund a sector. If your CRM needs 200 seed funds with war

2026-07-19 原文 →
AI 资讯

How We Caught 12 Breaking API Changes Before They Hit Main: Our Journey to Ephemeral Staging Environments

The moment we realized our staging environment was broken It was 3 PM on a Thursday, and our team was scrambling. A critical API change had just been merged to main, but the staging environment—our supposed safety net—was showing false positives. The integration tests passed, but the mobile app was completely broken in production. That's when we knew: our shared staging environment was failing us. The Problem: Shared Staging Is Broken by Design Like many engineering teams, we operated with a single, shared staging environment. Every developer deployed their changes to the same place, leading to: Deployment conflicts: "Who deployed that breaking change?" Cascading failures: One broken PR would block the entire team Test contamination: Data from one test would leak into another Delayed feedback: You'd only discover issues after merging your PR and deploying to staging The "works on my machine" syndrome, now at scale The worst part? Our API contracts were changing constantly, but we only discovered breaking changes during integration testing—often too late. The Solution: Ephemeral Environments per PR We made a radical change: every PR gets its own isolated, short-lived environment. Here's our architecture: Our Implementation Stack Infrastructure: Kubernetes (EKS) with namespace-per-PR Orchestration: Custom GitHub Action workflow Database: Isolated RDS instance per environment Contract Testing: Pact flow + OpenAPI validation Cleanup: AWS Lambda that runs every hour, destroying environments older than 2 hours The Game Changer: Automated Contract Testing The magic wasn't just in isolated environments—it was in what we did with them. Every time a PR deployed to its ephemeral environment, we ran: Consumer-Driven Contract Testing (Pact) Our mobile and web clients would verify their expectations against the actual deployed API. If a change broke what the client expected, the PR would fail. Provider Contract Validation We'd automatically verify that the deployed API matched ou

2026-07-18 原文 →
AI 资讯

Give your voice agent an email address for follow-ups

Every voice agent demo ends the same way. The bot wraps the call with a confident "Great — I'll email you the details and a confirmation," the human hangs up satisfied, and then nothing sends. There's no inbox behind the promise. The transcript lives in your voice stack, the "email" is a TODO nobody wired up, and the customer waits for a message that never arrives. It's the most common broken promise in conversational AI, and it's broken for a boring reason: the voice agent has no mailbox of its own. That's the gap this post closes. The interesting problem with voice agents isn't speech — your voice stack already handles the transcript, the turn-taking, and the summary. The interesting problem is the channel bridge : handing what happened on the call to a written, replyable email that comes from the agent and whose reply comes back to the agent . Voice in, email out, reply back in. No human in the loop, no shared support inbox, no spoofed noreply@ . The piece that makes this clean is a Nylas Agent Account — a real, owned email address that your voice agent sends from and receives at. I work on the Nylas CLI, so the terminal commands below are the exact ones I reach for, and I'll show both angles for every operation: the nylas command and the raw curl HTTP call. In practice your provisioning runs through the API and your ops glue runs through the CLI, so you'll want both. Why a real mailbox beats a fire-and-forget send Most teams reach for a transactional email API for this — SendGrid, SES, whatever's already in the stack — and fire a templated "here's your summary" off into the void. That works right up until the customer replies. Their reply hits a black hole ( noreply@ ), or worse, it lands in some shared support@ inbox where it's divorced from the call it answers. The agent that made the promise never sees the answer. An Agent Account is just a grant . It has a grant_id , and that ID works with every grant-scoped endpoint Nylas already exposes — Messages, Drafts,

2026-07-18 原文 →
AI 资讯

Build a webhook-driven email pipeline for your AI agent

Most "AI email" tutorials end with a while True loop that polls an inbox every thirty seconds, runs the new messages through a model, and sends a reply. It demos fine. Then you put it in front of real traffic and the cracks show up immediately: you're burning API calls to fetch nothing 99% of the time, your reaction latency is bounded by your poll interval, and the moment you scale to more than one inbox the polling cost multiplies. Polling an agent's inbox is wasteful. Webhooks are the right primitive for this. The mailbox already knows the instant a message lands — there's no reason to keep asking. What you actually want is a pipeline: inbound mail fans out to a verified ingest endpoint, lands on a queue, and gets picked up by workers that drive your agent runtime and send the reply. This post is about that architecture end to end — not a single feature, but the whole flow, with the parts that bite you in production (idempotency, retries, ordering, backpressure) called out honestly. I work on the Nylas CLI, so the terminal commands below are the exact ones I reach for when I'm wiring this up. I'll show the curl HTTP call and the CLI equivalent for every concrete step, because you'll use both: curl in your provisioning scripts, the CLI when you're poking at a live account. The mental model: an Agent Account is just a grant Before any of the pipeline matters, here's the one abstraction that makes the whole thing simple. An Agent Account is a Nylas grant — it has a grant_id , an inbox, an email address on a domain you own, and it speaks every grant-scoped endpoint you already know: Messages, Threads, Folders, Drafts, Attachments, Calendars, Events, Contacts, Webhooks. There's no OAuth token to refresh, no provider-specific quirks, no separate SDK. If you've built against a connected Gmail or Microsoft grant before, the data plane is identical. Nothing new to learn there. What's different is that the agent is a participant. It has its own address — support@yourcompany

2026-07-18 原文 →
AI 资讯

Make your email agent idempotent against duplicate webhooks

Most posts about "AI email agents" stop at the happy path: webhook fires, model drafts a reply, agent sends it. Demo works, screenshot looks great, ship it. Then it goes to production and the agent replies to the same customer twice ninety seconds apart, and now your "intelligent assistant" looks like a broken cron job. That second reply isn't a bug in your model. It's a property of the delivery system, and it's guaranteed to happen eventually. Nylas webhooks are at-least-once: the same event can arrive up to three times. If your handler treats every POST as a fresh event, every retry is a second action. For a logging pipeline that's harmless. For an agent that sends email on your behalf , a duplicate delivery is a duplicate reply, and a double-reply embarrasses the agent in front of the exact person you built it to impress. So this post is about the engineering of idempotency itself, applied to an Agent Account. Not "remember to dedupe" hand-waving — the actual moving parts: which field is the real dedup key, how to persist processed ids atomically, why you ack before you work, how to make the send path itself idempotent, and where a per-thread lock catches the race that dedup alone can't. I work on the Nylas CLI, so every terminal command below is one I've actually run, verified against nylas v3.1.27. What an Agent Account changes (and what it doesn't) An Agent Account is just a grant. It has a grant_id and works with every grant-scoped endpoint — Messages, Drafts, Threads, Folders — exactly like a connected Gmail or Microsoft account. The difference is it's an inbox the agent owns : support@yourcompany.com is the agent, not a human whose inbox the agent borrows. Inbound mail to that address fires the standard message.created webhook, the agent reads it, and the agent replies from its own address. Nothing new to learn on the data plane. That's the whole point of the grant abstraction — the idempotency work below is plain webhook-handling discipline, and it transfe

2026-07-18 原文 →
AI 资讯

Connect legacy tools to an agent mailbox over IMAP/SMTP

Most "AI email" integrations assume everything on the other side speaks REST. You wire up a webhook, you call POST /messages/send , and you move on. That works right up until you remember how much of your stack doesn't speak REST and never will: the ticketing system that ingests mail over IMAP, the backup script your predecessor wrote in 2014, the monitoring tool that only knows how to send SMTP, the compliance archiver that polls a mailbox every five minutes. None of those are getting rewritten to call an HTTP API for your demo. So here's the trick that makes a Nylas Agent Account genuinely useful in a real environment: it's not API-only. You can expose the same mailbox over IMAP and SMTP submission , hand the host, port, and credentials to one of those legacy tools, and let it read and send like it's talking to any old mail server. Meanwhile your agent drives that identical mailbox over the v3 API. Both surfaces hit one storage layer. A flag, move, or delete on either side shows up on the other within seconds. I work on the Nylas CLI, so the terminal commands below are the exact ones I reach for. As usual I'll show both angles for every operation — the raw curl against the API and the nylas command — because half the point of an Agent Account is that you can mix them freely. What you actually get An Agent Account is just a grant . It has a grant_id , and that grant_id works with every grant-scoped endpoint you already know — Messages, Drafts, Threads, Folders, Attachments, Contacts, Calendars, Events. There's nothing new to learn on the data plane. The IMAP/SMTP layer doesn't change that model. It adds a second door into the same room: One mailbox, two protocols. The API and the IMAP/SMTP server are two front-ends over the same backend. There is no sync job, no eventual-consistency window worth worrying about, no "API mailbox" versus "client mailbox." It's one mailbox. Legacy tools just work. Anything that can authenticate to an IMAP server with a username and pas

2026-07-18 原文 →
AI 资讯

How to Scrape Airbnb Listings and Prices in 2026 (No Code Required)

Heads-up: this post references a tool I built. It's a genuinely useful walkthrough either way — the technique applies to any Airbnb scraping project. If you've ever tried to scrape Airbnb, you already know the two walls you hit: the pages are rendered by JavaScript, and Airbnb aggressively blocks datacenter IPs. Below is the reliable way to get clean Airbnb data in 2026 — listing prices, ratings, coordinates, and discounts — without running a headless browser or babysitting proxies. The key insight: Airbnb ships its data in the HTML You don't need to render the page. Every Airbnb search response embeds the full result set as JSON inside a <script id="data-deferred-state-0"> tag. Parse that and you get structured data straight away — no DOM scraping, no selectors that break on the next redesign. The path to the results is: niobeClientData[*][1].data.presentation.staysSearch.results ├── searchResults[] // ~18 listings per page └── paginationInfo.pageCursors[] // all page cursors, upfront Each listing carries a base64-encoded ID in demandStayListing.id (decode it, take the segment after the last colon, and you have the numeric listing ID for airbnb.com/rooms/<id> ), a price line with discounts, avgRatingLocalized ("4.95 (123)"), and GPS coordinates. The two gotchas Datacenter IPs get blocked. You need residential proxies. If a response comes back without the data-deferred-state marker, you've been served a bot check — rotate to a fresh IP and retry. ~270 result cap per search. Airbnb won't paginate past ~15 pages. To cover a whole market, split into narrower searches (by price band or neighborhood) and dedupe by listing ID. The no-code way If you'd rather not maintain proxy pools and parsers, I published an Airbnb Scraper on Apify that does exactly the above. Paste a location or a full Airbnb search URL (every filter is honored), and get flat JSON/CSV back. curl -X POST "https://api.apify.com/v2/acts/ethanteague~airbnb-scraper/run-sync-get-dataset-items?token=YOUR_TOKE

2026-07-17 原文 →
AI 资讯

A FastAPI Agent Template Is Not Production-Ready Until Task Ownership Crosses Every Layer

Vercel published an OpenAI Agents SDK with FastAPI template on July 17, 2026. A template can remove setup work, but successful generation is not the production boundary that usually breaks. Task ownership is. Primary source: Vercel template, “OpenAI Agents SDK with FastAPI” . Before adopting any agent starter, I would add one vertical test: Alice must be able to create and cancel her task; Bob must not be able to read, stream, or cancel it—even if he guesses the task ID. State the cross-layer contract UI -> POST /tasks -> ownership row -> worker UI <- GET /tasks/:id <- authorization <- state UI <- event stream <- authorization <- events UI -> POST /tasks/:id/cancel -> authorization -> cancellation Use explicit states: queued -> running -> succeeded -> failed queued|running -> cancelling -> cancelled The database, API response, stream, and UI must agree on the same task and owner. Minimal schema create table tasks ( id text primary key , owner_id text not null , state text not null check ( state in ( 'queued' , 'running' , 'succeeded' , 'failed' , 'cancelling' , 'cancelled' )), created_at text not null , updated_at text not null , revision integer not null default 0 ); create table task_events ( task_id text not null , revision integer not null , kind text not null , payload text not null , primary key ( task_id , revision ) ); Do not derive ownership from a browser-supplied field. Resolve the authenticated principal on the server and store it when creating the task. FastAPI authorization seam from fastapi import Depends , FastAPI , HTTPException app = FastAPI () def current_user (): # Replace with verified session/JWT middleware. return { " id " : " alice " } def load_owned_task ( task_id : str , user = Depends ( current_user )): task = db_get_task ( task_id ) # application function if task is None or task [ " owner_id " ] != user [ " id " ]: # Avoid revealing whether another user's task exists. raise HTTPException ( status_code = 404 , detail = " task not found " )

2026-07-17 原文 →
AI 资讯

5 proyectos de agentes autónomos que revelan una infraestructura emergente

El ecosistema de agentes autónomos está evolucionando. Mientras la atención se centra en modelos y frameworks, empiezan a aparecer proyectos que cubren necesidades operativas básicas: comunicación, almacenamiento, finanzas. Aquí van cinco que vale la pena observar. 1. Apumail: el correo nativo para agentes Apumail ofrece direcciones de email que los agentes pueden crear y leer mediante una API REST plana. El contenido se negocia automáticamente: texto plano para agentes, HTML para humanos. Señal relevante: es el primer intento serio de darle a un agente un buzón de correo con el mismo estándar que usamos los humanos, sin adaptadores. Si los agentes empiezan a gestionar correspondencia, este tipo de servicio será indispensable. 2. RogerThat: chat entre agentes Una capa de mensajería en tiempo real diseñada para que agentes conversen entre sí. RogerThat no es un chat humano con bots, sino un canal donde los agentes coordinan acciones. Contexto: si varios agentes intervienen en un mismo workflow, necesitan un bus de eventos. RogerThat plantea que ese bus puede ser un chat, con las garantías de entrega y orden que eso implica. 3. DOBI: agente para DePIN y activos del mundo real Agent autónomo que opera sobre la cadena para gestionar infraestructuras físicas descentralizadas (DePIN). Ejecuta acciones on-chain a partir de decisiones tomadas por el modelo. Patrón: no es un simple bot de trading; apunta a mantenimiento de equipos, comprobación de sensores, distribución de incentivos. La frontera entre software y hardware se desdibuja. 4. CIDIF: financiamiento de I+D para agentes Plataforma que automatiza la presentación y seguimiento de solicitudes a fondos de innovación. El agente rellena formularios, adjunta documentación y trackea el estado. No obvio: la burocracia gubernamental es un entorno altamente estructurado (pocas decisiones abiertas, muchos campos fijos). Es un terreno ideal para agentes, aunque el ruido político lo opaque. 5. Orquesta: orquestación de flujos mu

2026-07-17 原文 →