Communitygithub.com

Ship de portfolio — Base Feishu → GitHub Pages + Actions

Convierte una tabla multidimensional de Feishu en un portfolio en vivo en GitHub Pages, con Actions que renuevan enlaces temporales de media. Para creadores con vídeo/imagen en Feishu (AI video, foto, diseño, librerías)—no blogs, ecommerce ni backends de escritura.

¿Qué es Ship de portfolio — Base Feishu → GitHub Pages + Actions?

Personal websites paso 3 (ship): feishu-portfolio-launch. SSOT de contenido+media en Feishu → sitio generado → GitHub Pages + refresco programado de enlaces. Ruta de publicación para creadores.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add Jane-xiaoer/feishu-portfolio-launch

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Lanzamiento de Portafolio en Feishu

¿Qué hace esta Skill?

En una frase: Dame el enlace de tu tabla multidimensional de Feishu, construyo el sitio de portafolio y automatizo que los enlaces temporales de Feishu expiren.

Entregables por defecto:

  • index.html o página frontend estática
  • api/videos.json
  • api/covers.json
  • api/portfolio.json
  • refresh.py
  • .github/workflows/refresh.yml
  • Capa de interacción frontend con animaciones (CSS / JS / Canvas / Three.js)

Recursos de plantilla integrados:

Objetivo:

  • Sitio desplegado en GitHub Pages
  • Los enlaces multimedia de Feishu se actualizan automáticamente cada 12 horas mediante GitHub Actions
  • El usuario no necesita mantener su computadora encendida
  • La página no es solo estática: incluye al menos un conjunto completo de animaciones de entrada, desplazamiento, hover y transición

Escenarios de uso

✅ Adecuado para:

  • Portafolios de videos/imágenes con IA
  • Galerías de fotografía, diseño y muestras creativas
  • Sitios de demostración de casos de clientes
  • Cualquier escenario donde "el contenido está en archivos adjuntos de Feishu y el frontend solo muestra"

❌ No adecuado para:

  • Blogs con texto e imágenes
  • Sistemas de comercio electrónico, pagos o inicio de sesión
  • Sitios que requieren escritura en base de datos y lógica de backend

Principio central

No trates las URLs temporales de Feishu como recursos permanentes.

Las URLs de reproducción/descarga de archivos adjuntos de Feishu caducan. La solución correcta no es que el usuario ejecute un script periódicamente en su computadora local, sino:

  1. Leer los registros más recientes de la tabla multidimensional de Feishu
  2. Llamar a la API de Feishu para convertir el file_token del adjunto en una URL temporal
  3. Generar api/*.json
  4. Enviar de vuelta al repositorio de GitHub
  5. Hacer que GitHub Pages se redespliegue automáticamente

Es decir:

Feishu Bitable -> refresh.py -> api/*.json -> GitHub Pages


Flujo de ejecución

Paso 0: Verificación del entorno

Primero verifica que las herramientas necesarias para la inicialización estén disponibles localmente:

for cmd in node python3 gh git; do
  which "$cmd" >/dev/null 2>&1 && echo "OK  $cmd" || echo "MISS $cmd"
done
lark-cli --version >/dev/null 2>&1 && echo "OK  lark-cli" || echo "MISS lark-cli"
gh auth status >/dev/null 2>&1 && echo "OK  GitHub auth" || echo "MISS GitHub auth"

Si falta alguna herramienta, pide al usuario que la instale. Si gh no está autenticado, completa el inicio de sesión en GitHub.


Paso 1: Obtener el Base de Feishu y la tabla de datos correcta

Pide al usuario el enlace de la tabla multidimensional de Feishu, por ejemplo:

https://my.feishu.cn/base/AbCdEfGhIjk

Extrae el app_token de la URL.

Luego lista todas las tablas:

lark-cli api GET "/open-apis/bitable/v1/apps/${APP_TOKEN}/tables"

No selecciones la primera tabla por defecto. Muchos Bases contienen simultáneamente "tablas de plantilla vacía" y "tablas de materiales con obras reales". Continúa leyendo los registros y verifica:

  • ¿Qué tabla tiene campos de archivos adjuntos reales?
  • ¿Qué tabla tiene el número correcto de registros?
  • ¿Qué tabla tiene nombres de campo que el usuario quiere mostrar?

Prioriza buscar estos campos:

  • Campo de video: Muestra / Video / Adjunto
  • Campo de portada: Portada / Imagen de portada / Póster / Imagen
  • Campo de título: Contenido / Título / Nombre de la obra
  • Campo de categoría: Tipo / Categoría
  • Campo de duración: Duración
  • Campo de herramienta: Herramienta de IA / Herramienta
  • Campo de orden: Número de orden

Si una tabla solo tiene campos de plantilla vacía como Texto / Selección única / Fecha / Adjunto, sigue cambiando de tabla, no generes el sitio.


Paso 2: Verificar los permisos de Feishu

Para que GitHub Actions pueda actualizarse automáticamente, la aplicación de Feishu debe poder al menos:

  • Leer los registros de la tabla multidimensional
  • Leer los enlaces multimedia de los archivos adjuntos

El plan de ejecución debe depender explícitamente de estos 4 secretos:

  • LARK_APP_ID
  • LARK_APP_SECRET
  • LARK_BASE_TOKEN
  • LARK_TABLE_ID

Si el usuario ya tiene una configuración de aplicación de Feishu utilizable localmente, se puede reutilizar. De lo contrario, se debe indicar claramente que vaya a la plataforma abierta de Feishu para agregar permisos y claves.


Paso 3: Exportar datos estructurados de las obras

No solo extraigas una lista de file_token. Construye un conjunto de datos estructurados que el frontend pueda consumir directamente, que incluya al menos:

  • title
  • categories
  • duration
  • tools
  • order
  • video_token
  • cover_token

Salida recomendada:

  • api/portfolio.json: Array completo de obras
  • api/videos.json: video_token -> tmp_download_url
  • api/covers.json: cover_token -> tmp_download_url

La estructura de ejemplo se puede consultar directamente en assets/portfolio.sample.json del repositorio.

El frontend puede seguir usando HTML + JS estático, o renderizarse completamente desde portfolio.json.


Paso 4: Generar la página frontend

Genera una página estática por defecto, que debe cumplir:

  • Cuadrícula de obras responsiva
  • Filtro por categoría
  • Reproducción al hacer clic en la tarjeta
  • Reproducción en pantalla completa ampliada
  • Permitir que solo se reproduzca un video a la vez
  • Portada: usar preferentemente el campo de portada de Feishu; si no hay portada, permitir degradación sin póster

Los efectos de animación deben entregarse juntos por defecto, no solo una página estática que "se pueda abrir":

  • La pantalla de inicio debe tener al menos un conjunto de animaciones de entrada, como título, descripción, números estadísticos que aparecen gradualmente con fade-up
  • La navegación debe permitir cambios en blur / background / border al desplazarse
  • Las tarjetas deben tener al menos una retroalimentación ligera en hover, como elevación, escala, máscara, cambio de color de título
  • Las transiciones entre páginas o secciones deben ser suaves, no cambios bruscos
  • Las secciones de información como Acerca de / Contacto / Habilidades deben tener preferentemente scroll reveal
  • Si el usuario desea una representación visual más intensa, se pueden agregar animaciones de fondo con Canvas o Three.js

Límites de implementación:

  • Priorizar el uso de transiciones CSS nativas / keyframes / IntersectionObserver
  • Usar requestAnimationFrame solo cuando se necesite un movimiento de fondo continuo
  • Si se usa Three.js, asegurar que no haya espacios en blanco, bloqueos o que oculte el contenido principal en dispositivos móviles
  • Las animaciones no deben afectar la reproducción de video, el filtrado, las ventanas emergentes, el desplazamiento en móviles ni la legibilidad de la pantalla de inicio
  • Proporcionar una ruta de degradación por defecto: si el script falla, el texto y el contenido deben seguir siendo visibles

Principios de vinculación de datos:

  • No codificar URLs caducadas en el HTML
  • La página debe obtener /api/videos.json y /api/covers.json en tiempo de ejecución
  • O bien, obtener directamente /api/portfolio.json para renderizar las tarjetas

Si el usuario ya tiene un sitio existente, priorizar mantener el estilo visual actual y solo reemplazar la fuente de datos y el mecanismo de actualización.

Si el usuario menciona explícitamente que quiere referenciar el estilo de un sitio existente, priorizar reutilizar estos tipos de animación:

  • Animación de entrada del texto hero
  • Transición de estado de desplazamiento del filtro / navegación sticky
  • Efecto hover de tarjetas en masonry
  • Transición de fundido de páginas
  • Revelación escalonada en la sección Acerca de
  • Movimiento de fondo opcional con Three.js / Canvas

Paso 5: Crear el repositorio y desplegar GitHub Pages

Flujo estándar:

gh repo create <repo-name> --public --source=. --remote=origin --push

Luego confirma que la fuente de Pages sea:

  • branch: main
  • path: /

Verifica:

gh api repos/<owner>/<repo>/pages

Debe confirmar:

  • Pages está habilitado
  • cname es correcto (si hay dominio personalizado)
  • source apunta a main y al directorio raíz

Paso 6: Generar el script de actualización automática

El script de actualización debe seguir esta ruta:

  1. Obtener tenant_access_token con app_id + app_secret
  2. Leer los registros de Bitable
  3. Extraer los tokens de archivos adjuntos de video y portada de los registros
  4. Llamar a batch_get_tmp_download_url en lotes
  5. Escribir api/videos.json, api/covers.json, api/portfolio.json

Requisitos clave:

  • Soporte para paginación al leer registros
  • Solicitudes en lotes agrupando 5 tokens
  • No codificar la lista de tokens en el script
  • Generar dinámicamente desde los registros reales de la tabla
  • Permitir múltiples nombres de campo candidatos

Nombre de archivo recomendado:

  • refresh.py

Priorizar copiar directamente la plantilla incluida en la skill:

cp ~/.claude/skills/feishu-portfolio-launch/assets/refresh.py ./refresh.py

Luego solo modificar el array de campos candidatos, sin codificar tokens o URLs específicos.


Paso 7: Generar el flujo de trabajo de GitHub Actions

Ya no uses launchd local como plan por defecto. El plan por defecto debe ser GitHub Actions.

El flujo de trabajo debe:

  • Soportar workflow_dispatch
  • Soportar schedule, por defecto ejecutar cada 12 horas
  • Ejecutar python refresh.py
  • Confirmar automáticamente api/videos.json, api/covers.json, api/portfolio.json

Secretos estándar:

  • LARK_APP_ID
  • LARK_APP_SECRET
  • LARK_BASE_TOKEN
  • LARK_TABLE_ID

Archivo estándar:

  • .github/workflows/refresh.yml

Priorizar copiar directamente la plantilla incluida en la skill:

mkdir -p .github/workflows
cp ~/.claude/skills/feishu-portfolio-launch/assets/refresh.yml .github/workflows/refresh.yml

Paso 8: Configurar los Secretos en el repositorio

Si el entorno actual ya tiene estos valores y el usuario te indica explícitamente que los concretes, configúralos directamente:

gh secret set LARK_APP_ID -R <owner>/<repo>
gh secret set LARK_APP_SECRET -R <owner>/<repo>
gh secret set LARK_BASE_TOKEN -R <owner>/<repo>
gh secret set LARK_TABLE_ID -R <owner>/<repo>

Luego verifica:

gh secret list -R <owner>/<repo>

Si falta algún valor, detente aquí e indica claramente al usuario cuál falta, no lo inventes.


Paso 9: Activar manualmente y verificar toda la cadena

Después de la configuración, ejecuta manualmente el flujo de trabajo una vez:

gh workflow run refresh.yml -R <owner>/<repo>
gh run list -R <owner>/<repo> --limit 3
gh run watch <run-id> -R <owner>/<repo> --exit-status

Luego verifica el resultado en línea:

python3 - <<'PY'
import json, urllib.request, time
url = f'https://<dominio-o-url-pages>/api/videos.json?t={int(time.time())}'
with urllib.request.urlopen(url, timeout=20) as r:
    data = json.load(r)
print(data.get('_refreshed_at'))
print(data.get('_count'))
PY

Luego prueba una muestra de 1 video:

  • El código de estado debe ser 206 o 200
  • content-type debe ser video/mp4 o un tipo de medio reproducible

Si el api/videos.json en línea aún tiene la hora anterior:

  • Primero verifica si el despliegue de Pages se ha completado
  • Luego verifica si el flujo de trabajo realmente confirmó el nuevo JSON
  • Luego confirma si la fuente de Pages apunta a la rama y directorio correctos

Paso 10: Vinculación de dominio

Si el usuario quiere un dominio personalizado, hazlo:

  • Archivo CNAME
  • Configuración de dominio personalizado de GitHub Pages
  • Guía de configuración de DNS

Esta parte sigue el flujo estándar de GitHub Pages, no necesita estar acoplada a la lógica de Feishu.


Explicación predeterminada para el usuario

Cuando te encuentres con "el sitio se abre pero el video no se reproduce", prioriza juzgar:

  1. ¿api/videos.json sigue siendo antiguo?
  2. ¿La URL de Feishu dentro ha caducado?
  3. ¿El flujo de trabajo de actualización automática falló?
  4. ¿Pages aún no se ha redesplegado?

Por defecto, no sospeches primero del reproductor ni del estilo del frontend.

Si el usuario dice "la página está muy muerta" o "quiero que tenga más vida como un portafolio", agrega una capa de animación por defecto, no solo cambies colores y tipografía.


Criterios de éxito

Una vez completada esta Skill, al menos debe cumplir:

  • El sitio ya está en línea
  • GitHub Pages es accesible
  • Los videos se pueden reproducir
  • El repositorio tiene un flujo de trabajo de actualización automática
  • El repositorio ya tiene los 4 secretos LARK_*
  • La activación manual del flujo de trabajo fue exitosa
  • El _refreshed_at de api/videos.json en línea muestra la hora actualizada

Lo que ya no se debe hacer por defecto

  • No generar launchd local por defecto
  • No depender de que el Mac del usuario esté encendido permanentemente
  • No codificar todos los file_token
  • No continuar solo con la primera tabla
  • No generar solo videos.json, ignorando portadas y registros estructurados

Implementación de referencia

Si necesitas un enfoque ya verificado, reutiliza directamente las plantillas incluidas en el repositorio de la skill:

  • assets/refresh.py
  • assets/refresh.yml
  • assets/portfolio.sample.json

En el proyecto real, finalmente se generarán estos archivos:

  • refresh.py
  • .github/workflows/refresh.yml
  • api/videos.json
  • api/covers.json
  • api/portfolio.json

Prioriza reutilizar el patrón del repositorio existente, luego adapta según el estilo del sitio del usuario.

Skills relacionados