惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
阮一峰的网络日志
阮一峰的网络日志
G
Google Developers Blog
J
Java Code Geeks
Blog — PlanetScale
Blog — PlanetScale
大猫的无限游戏
大猫的无限游戏
云风的 BLOG
云风的 BLOG
Vercel News
Vercel News
L
LangChain Blog
Hugging Face - Blog
Hugging Face - Blog
T
The Blog of Author Tim Ferriss
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Stack Overflow Blog
Stack Overflow Blog
P
Proofpoint News Feed
腾讯CDC
博客园_首页
博客园 - 聂微东
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
D
DataBreaches.Net
Microsoft Security Blog
Microsoft Security Blog
有赞技术团队
有赞技术团队
博客园 - 叶小钗

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Replace Zapier With 50 Lines of Python (Save $50/Month)
Brad · 2026-05-14 · via DEV Community

Brad

Zapier is brilliant but expensive. $50-100/month for automations that Python handles in 50 lines of code. Here's how to cut that bill to zero.

What Zapier Actually Does

Zapier connects apps through triggers and actions:

  • "When I get an email with attachment → save to Google Drive"
  • "When form submitted → add row to Google Sheet + send Slack notification"
  • "Every day at 9am → pull data from API → send report email"

Python can do every one of these. The difference: you own the code and run it for free.

The Core Pattern: Webhooks + HTTP Requests

Most Zapier automations boil down to:

  1. Receive a trigger (webhook, time, email, API poll)
  2. Transform the data
  3. Send it somewhere
import httpx
from flask import Flask, request, jsonify
import json

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    data = request.json
    print(f"Received: {json.dumps(data, indent=2)}")

    # Transform the data
    processed = transform_data(data)

    # Send somewhere
    result = forward_to_slack(processed)

    return jsonify({"status": "ok", "forwarded": result})

def transform_data(data: dict) -> dict:
    # Your business logic here
    return {
        "text": f"New submission: {data.get('name', 'Unknown')}",
        "details": data.get('message', '')
    }

def forward_to_slack(data: dict) -> bool:
    webhook_url = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
    r = httpx.post(webhook_url, json={"text": data['text']})
    return r.status_code == 200

Enter fullscreen mode Exit fullscreen mode

Email → Google Sheets (Classic Zapier Workflow)

import imaplib
import email
import gspread
from google.oauth2.service_account import Credentials
from datetime import datetime
import re

def check_emails_and_log():
    # Connect to Gmail
    mail = imaplib.IMAP4_SSL('imap.gmail.com')
    mail.login('you@gmail.com', 'your-app-password')
    mail.select('INBOX')

    # Search for unread emails from specific sender
    _, messages = mail.search(None, 'UNSEEN FROM "orders@shop.com"')

    # Connect to Google Sheets
    creds = Credentials.from_service_account_file('service_account.json',
        scopes=['https://spreadsheets.google.com/feeds'])
    gc = gspread.authorize(creds)
    sheet = gc.open('Order Log').sheet1

    for msg_id in messages[0].split():
        _, msg_data = mail.fetch(msg_id, '(RFC822)')
        msg = email.message_from_bytes(msg_data[0][1])

        subject = msg['subject']
        sender = msg['from']
        date = msg['date']
        body = get_body(msg)

        # Extract order number from subject (adjust regex for your format)
        order_match = re.search(r'Order #(\d+)', subject)
        order_num = order_match.group(1) if order_match else 'unknown'

        # Append to sheet
        sheet.append_row([
            datetime.now().strftime('%Y-%m-%d %H:%M'),
            order_num,
            sender,
            subject,
            body[:200]  # First 200 chars of body
        ])
        print(f"Logged order {order_num}")

        # Mark as read
        mail.store(msg_id, '+FLAGS', '\\Seen')

    mail.logout()

def get_body(msg) -> str:
    if msg.is_multipart():
        for part in msg.walk():
            if part.get_content_type() == "text/plain":
                return part.get_payload(decode=True).decode()
    return msg.get_payload(decode=True).decode()

Enter fullscreen mode Exit fullscreen mode

Timed Automations (Replacing Zapier Schedules)

import schedule
import time
import httpx
from datetime import datetime

def daily_report():
    """Pull data from your API and email a report."""
    # Get today's data
    r = httpx.get('https://your-api.com/stats/today', 
                  headers={'Authorization': 'Bearer YOUR_TOKEN'})
    data = r.json()

    # Format report
    report = f"""
    Daily Report - {datetime.now().strftime('%Y-%m-%d')}

    Revenue: ${data['revenue']:.2f}
    New signups: {data['signups']}
    Active users: {data['active_users']}
    """

    # Send email
    send_email("Daily Report", report, "you@company.com")
    print("Daily report sent!")

def weekly_cleanup():
    """Archive old records, free up space."""
    print("Running weekly cleanup...")
    # Your cleanup logic here

# Schedule tasks
schedule.every().day.at("09:00").do(daily_report)
schedule.every().monday.at("08:00").do(weekly_cleanup)

print("Scheduler running...")
while True:
    schedule.run_pending()
    time.sleep(60)

Enter fullscreen mode Exit fullscreen mode

Form Submission → Multiple Destinations

Replace the "$20/month Zapier plan" for form routing:

from flask import Flask, request, jsonify
import httpx, smtplib
from email.mime.text import MIMEText

app = Flask(__name__)

@app.route('/contact', methods=['POST'])
def handle_contact():
    data = request.json or request.form.to_dict()
    name = data.get('name')
    email = data.get('email')  
    message = data.get('message')

    results = {}

    # 1. Send confirmation email to user
    send_confirmation_email(email, name)
    results['confirmation_email'] = True

    # 2. Notify you via Slack
    notify_slack(name, email, message)
    results['slack'] = True

    # 3. Add to your CRM (e.g., Airtable)
    add_to_crm(name, email, message)
    results['crm'] = True

    # 4. Log to Google Sheet
    log_to_sheet(name, email, message)
    results['sheet'] = True

    return jsonify({"success": True, "results": results})

def notify_slack(name, email, message):
    slack_webhook = "https://hooks.slack.com/services/YOUR/WEBHOOK"
    httpx.post(slack_webhook, json={
        "text": f"📬 New contact from {name} ({email}):\n{message[:200]}"
    })

def add_to_crm(name, email, message):
    # Airtable example
    httpx.post(
        'https://api.airtable.com/v0/YOUR_BASE_ID/Contacts',
        headers={'Authorization': 'Bearer YOUR_KEY'},
        json={'fields': {'Name': name, 'Email': email, 'Notes': message}}
    )

Enter fullscreen mode Exit fullscreen mode

The Math on Zapier vs Python

Zapier Python
Monthly cost $20-100 $0
Task limits 750-50k/month Unlimited
Custom logic Limited Full code
Debugging Black box Full logs
Setup time 10 minutes 30-60 minutes

For less than 1 hour of setup, you eliminate a $50-100/month subscription permanently.

Running It for Free

Run your automation scripts on:

  • Your own server (even a Raspberry Pi)
  • Oracle Free Tier (always-free VMs)
  • GitHub Actions (free for public repos, 2000 min/month private)
  • PythonAnywhere free tier (for simple scripts)

Already built and packaged: The Python Business Automation Toolkit includes pre-built scripts for email automation, scheduling, form processing, and more — all configured and ready to customize for your business.

Get the toolkit for $29 — includes email-to-sheet automation, Slack notifications, scheduled reports, and invoice processing.