Skip to content
Documentation
Command

/start-11-3.es

Lesson command

From plugin
ai-agent-camp
345200 skills8 agents200 commands
Install
$ npx -y skills add minicoohei/ai-agent-camp --agent claude-code

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/start-11-3.es

Context preview

What this command does when you run it.

Lesson command

Command definition

start-11-3.es.md
description: "Lesson command"
chapter: "courses/aiagent/lesson03-core/module11-github-actions"
duration: "~25 min"
prerequisites: ["start-11-2"]
level: "intermediate"
tags: ["github-actions", "news", "email", "slack", "webhook", "cron"]
nonInteractiveMode: deferred

๐ŸŽ“ Lesson 11-3: Flujo de trabajo de obtencion de noticias y distribucion por correo/Slack

๐Ÿ“ Lo que hara en esta sesion

**Leccion 11-3: Obtencion de noticias y distribucion por correo/Slack**!

| Elemento | Contenido | |------|------| | Objetivo | Construir un flujo de trabajo en GitHub Actions que obtiene noticias automaticamente y las distribuye por correo electronico y Slack | | Duracion | ~25 min | | Habilidades utilizadas | GitHub Actions, Python (requests), Slack Webhook, smtplib | | Requisitos previos | Leccion 11-2 completada (comprension de la configuracion de Secrets) |

**Flujo de la sesion:** 1. Creacion del script de obtencion de noticias 2. Implementacion del envio por correo electronico 3. Configuracion de notificaciones via Slack Webhook 4. Creacion del flujo de trabajo de GitHub Actions 5. Configuracion de Secrets y pruebas de funcionamiento

Al final de esta sesion, tendra un pipeline que recopila noticias periodicamente y las distribuye automaticamente por correo electronico y Slack.

> **๐Ÿ’ก Consejo**: Si la respuesta de la IA se detiene a mitad de camino, escriba "por favor continue" o "siga adelante" para reanudar.

---

๐ŸŽฏ Verificacion de preparacion

**Configuracion de AskQuestion:**

{
  "title": "๐ŸŽฏ Verificacion previa a la sesion",
  "questions": [{
    "id": "readiness",
    "prompt": "Esta listo/a?",
    "options": [
      {"id": "ready", "label": "Listo! Comencemos"},
      {"id": "check_prereq", "label": "Verificar requisitos previos"},
      {"id": "different_lesson", "label": "Ir a otra leccion"}
    ]
  }]
}

(ready โ†’ Ir al Step 1) (check_prereq โ†’ Verificar que la Leccion 11-2 esta completada. Verificar la existencia del directorio `.github/workflows/`) (different_lesson โ†’ Mostrar lista de modulos)

---

๐Ÿš€ Step 1: Creacion del script de obtencion de noticias

{
  "title": "๐Ÿš€ Step 1: Script de obtencion de noticias",
  "questions": [{
    "id": "step_action",
    "prompt": "Crearemos un script en Python que obtiene noticias desde feeds RSS o la News API.",
    "options": [
      {"id": "practice", "label": "Continuar"},
      {"id": "review", "label": "Revisar el funcionamiento de RSS/API"},
      {"id": "skip", "label": "Omitir"}
    ]
  }]
}

**Indicaciones tras la seleccion (ejemplo)**:

Crear `tools/fetch_news.py`:

#!/usr/bin/env python3
"""Script de obtencion de noticias โ€” Recopila noticias desde feeds RSS"""
import json
import xml.etree.ElementTree as ET
from datetime import datetime
import requests

# URLs de feeds RSS (ejemplo: Hacker News, TechCrunch)
RSS_FEEDS = [
    {"name": "Hacker News", "url": "https://hnrss.org/newest?count=5"},
    {"name": "TechCrunch", "url": "https://techcrunch.com/feed/"},
]

def fetch_rss(url, max_items=5):
    """Obtener noticias desde un feed RSS"""
    resp = requests.get(url, timeout=30)
    resp.raise_for_status()
    root = ET.fromstring(resp.text)
    items = []
    for item in root.iter("item"):
        title = item.findtext("title", "")
        link = item.findtext("link", "")
        pub_date = item.findtext("pubDate", "")
        items.append({"title": title, "link": link, "pubDate": pub_date})
        if len(items) >= max_items:
            break
    return items

def main():
    all_news = []
    for feed in RSS_FEEDS:
        try:
            items = fetch_rss(feed["url"])
            all_news.append({"source": feed["name"], "items": items})
        except Exception as e:
            print(f"[WARN] {feed['name']}: {e}")
    
    # Salida JSON
    output = {
        "generated_at": datetime.utcnow().isoformat(),
        "feeds": all_news
    }
    with open("output/news_digest.json", "w") as f:
        json.dump(output, f, ensure_ascii=False, indent=2)
    print(f"Obtencion completada: {sum(len(f['items']) for f in all_news)} noticias")
    return output

if __name__ == "__main__":
    main()
mkdir -p output && python tools/fetch_news.py

**Resultado esperado**: Los datos de noticias se guardan en `output/news_digest.json`.

---

๐Ÿš€ Step 2: Implementacion del envio por correo electronico

{
  "title": "๐Ÿš€ Step 2: Envio por correo",
  "questions": [{
    "id": "step_action",
    "prompt": "Agregaremos el proceso de envio de las noticias obtenidas por correo electronico.",
    "options": [
      {"id": "practice", "label": "Continuar"},
      {"id": "review", "label": "Revisar el uso de smtplib"},
      {"id": "skip", "label": "Omitir"}
    ]
  }]
}

**Indicaciones tras la seleccion (ejemplo)**:

Agregar la funcion de envio a `tools/fetch_news.py`:

import smtplib
from email.mime.text import MIMEText
import os

def send_email(news_data):
    """Enviar resumen de noticias por correo electronico"""
    smtp_user = os.environ.get("SMTP_USER", "")
    smtp_pass = os.environ.get("SMTP_PASS", "")
    to_email = os.environ.get("NOTIFY_EMAIL", smtp_user)
    
    if not smtp_user or not smtp_pass:
        print("[SKIP] Envio de correo omitido: credenciales SMTP no configuradas")
        return

    # Crear cuerpo del correo
    body_lines = [f"# Resumen de noticias ({news_data['generated_at'][:10]})\n"]
    for feed in news_data["feeds"]:
        body_lines.append(f"\n## {feed['source']}")
        for item in feed["items"]:
            body_lines.append(f"- [{item['title']}]({item['link']})")
    
    body = "\n".join(body_lines)
    msg = MIMEText(body, "plain", "utf-8")
    msg["Subject"] = f"Resumen de noticias {news_data['generated_at'][:10]}"
    msg["From"] = smtp_user
    msg["To"] = to_email

    with smtplib.SMTP("smtp.gmail.com", 587) as server:
        server.starttls()
        server.login(smtp_user, smtp_pass)
        server.send_message(msg)
Read more
Ships withai-agent-camp

AI Agent Training for Non-Engineers - Complete Guide to Claude Code / Cursor / Codex ### โš ๏ธ Before you clone Official repository (maintained by the authors): Running AI agents from this repo grants them shell, file-write, and external-API permissions on your

Get the whole plugin