Communitygithub.com

Ship de portfolio — Base Feishu → GitHub Pages + Actions

Transforme uma tabela multidimensional Feishu em portfolio ao vivo no GitHub Pages, com Actions que renovam links temporários de mídia. Para criadores com assets no Feishu — não blogs, ecommerce ou backends de escrita.

O que é Ship de portfolio — Base Feishu → GitHub Pages + Actions?

Personal websites passo 3 (ship): feishu-portfolio-launch. SSOT Feishu → site → Pages + refresh agendado.

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

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Lançamento de Portfólio no Feishu

O que esta Skill faz

Em uma frase: Dê-me o link da tabela multidimensional do Feishu, eu construo o site de portfólio e automatizo o problema de "links temporários do Feishu expirarem".

Entregas padrão:

  • index.html ou página front-end estática
  • api/videos.json
  • api/covers.json
  • api/portfolio.json
  • refresh.py
  • .github/workflows/refresh.yml
  • Camada de interação front-end com animações (CSS / JS / Canvas / Three.js)

Recursos de modelo integrados:

Resultado desejado:

  • Site implantado no GitHub Pages
  • Links de mídia do Feishu são atualizados automaticamente a cada 12 horas pelo GitHub Actions
  • O usuário não precisa manter o computador ligado
  • A página não é puramente estática; pelo menos possui um conjunto completo de animações de entrada / rolagem / foco / transição de página

Cenários de Uso

✅ Adequado para:

  • Portfólios de vídeo / imagem com IA
  • Bibliotecas de amostras de fotografia, design, criativos
  • Sites de demonstração de casos de clientes
  • Qualquer cenário onde "o conteúdo está nos anexos do Feishu e o front-end só precisa exibir"

❌ Não adequado para:

  • Blogs com texto e imagem
  • Sistemas de e-commerce, pagamento, login
  • Sites que precisam de gravação em banco de dados e lógica de negócios back-end

Princípios Principais

Não trate URLs temporárias do Feishu como recursos permanentes.

Os URLs de reprodução / download dos anexos do Feishu expiram. A abordagem correta não é fazer o usuário executar um script agendado localmente no computador, mas sim:

  1. Ler os registros mais recentes da tabela multidimensional do Feishu
  2. Chamar a API do Feishu para resolver o file_token do anexo em um URL temporário
  3. Gerar api/*.json
  4. Enviar de volta para o repositório GitHub
  5. Deixar o GitHub Pages reimplantar automaticamente

Ou seja:

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


Fluxo de Execução

Passo 0: Verificação do Ambiente

Primeiro, verifique se as ferramentas necessárias para a inicialização estão disponíveis 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"

Se faltar alguma ferramenta, peça ao usuário para instalá-la.
Se o gh não estiver autenticado, conclua a autenticação do GitHub primeiro.


Passo 1: Obter a Base do Feishu e a Tabela de Dados Correta

Peça ao usuário o link da tabela multidimensional do Feishu, por exemplo:

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

Extraia o app_token do URL.

Em seguida, liste todas as tabelas:

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

Não selecione a primeira tabela por padrão.
Muitas Bases têm simultaneamente "tabelas de modelo vazias" e "tabelas de materiais com obras reais". Continue lendo registros e validando:

  • Qual tabela tem campos de anexo reais
  • Qual tabela tem a contagem correta de registros
  • Qual tabela tem nomes de campo que o usuário deseja exibir

Priorize a busca por estes campos:

  • Campo de vídeo: 样片 / 视频 / 附件
  • Campo de capa: 封面 / 封面图 / 海报 / 图片
  • Campo de título: 内容 / 标题 / 作品名称
  • Campo de categoria: 类型 / 分类
  • Campo de duração: 时长
  • Campo de ferramenta: AI工具 / 工具
  • Campo de ordenação: 序号

Se uma tabela tiver apenas campos de modelo vazios como 文本 / 单选 / 日期 / 附件, continue trocando de tabela; não gere o site.


Passo 2: Verificar Permissões do Feishu

Para que o GitHub Actions possa atualizar automaticamente, o aplicativo do Feishu deve pelo menos:

  • Ler registros da tabela multidimensional
  • Ler links de mídia dos anexos

O plano de execução deve depender explicitamente destes 4 secrets:

  • LARK_APP_ID
  • LARK_APP_SECRET
  • LARK_BASE_TOKEN
  • LARK_TABLE_ID

Se o usuário já tiver uma configuração de aplicativo do Feishu funcional na máquina local, pode reutilizá-la. Caso contrário, informe claramente ao usuário que é necessário complementar as permissões e chaves no portal de desenvolvimento do Feishu.


Passo 3: Exportar Dados Estruturados das Obras

Não extraia apenas a lista de file_token.
Construa dados estruturados que o front-end possa consumir diretamente, contendo pelo menos:

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

Saída recomendada:

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

Um exemplo de estrutura pode ser consultado diretamente no arquivo assets/portfolio.sample.json do repositório.

O front-end pode continuar usando HTML + JS estáticos, ou ser totalmente renderizado a partir de portfolio.json.


Passo 4: Gerar Página Front-end

Por padrão, gere uma página estática, com os seguintes requisitos:

  • Grade de obras responsiva
  • Filtro por categoria
  • Clique no cartão para reproduzir
  • Reprodução em tela cheia ampliada
  • Permitir apenas um vídeo reproduzindo por vez
  • Priorizar o campo de capa do Feishu para a capa; quando não houver capa, permitir degradação para sem poster

Animações devem ser entregues junto por padrão; não fazer apenas uma página estática "que funciona":

  • A tela inicial deve ter pelo menos um conjunto de animações de entrada, como título, descrição, números estatísticos aparecendo gradualmente (fade-up)
  • A navegação, após a rolagem, deve permitir mudanças de desfoque / fundo / borda
  • O hover nos cartões deve ter pelo menos um feedback leve, como levantar, escalar, máscara, mudança de cor do título
  • A transição entre páginas ou seções deve ter uma transição suave, sem cortes abruptos
  • Para áreas de informação como Sobre / Contato / Módulo de habilidades, priorizar scroll reveal
  • Se o usuário desejar uma apresentação visual mais forte, pode-se adicionar animações de fundo com Canvas ou Three.js

Limites de implementação:

  • Priorizar CSS nativo transition / keyframes / IntersectionObserver
  • Usar requestAnimationFrame apenas para movimentos de fundo contínuos
  • Se usar Three.js, garantir que não fique em branco, trava ou oculte o conteúdo principal em dispositivos móveis
  • As animações não podem afetar a reprodução de vídeo, filtragem, pop-ups, rolagem em dispositivos móveis e legibilidade da tela inicial
  • Fornecer um caminho de degradação por padrão; texto e conteúdo devem permanecer visíveis se o script falhar

Princípio de vinculação de dados:

  • HTML não deve conter URLs expiradas escritas diretamente
  • A página, em tempo de execução, busca /api/videos.json e /api/covers.json
  • Ou busca /api/portfolio.json diretamente para renderizar os cartões

Se o usuário já tiver um site, priorize manter o estilo visual existente, apenas substituindo a fonte de dados e o mecanismo de atualização.

Se o usuário mencionar explicitamente referência ao estilo de um site existente, priorize reutilizar esses tipos de animação:

  • Animação de entrada do texto hero
  • Transição de estado de rolagem do filtro / nav sticky
  • Efeito hover dos cartões masonry
  • Transição de fade in/out da página
  • Stagger reveal da página Sobre
  • Movimento de fundo opcional com Three.js / Canvas

Passo 5: Criar Repositório e Implantar GitHub Pages

Fluxo padrão:

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

Em seguida, confirme se a origem do Pages é:

  • branch: main
  • path: /

Verifique:

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

Deve confirmar:

  • Pages está habilitado
  • cname está normal (se houver domínio personalizado)
  • source aponta para main e o diretório raiz

Passo 6: Gerar Script de Atualização Automática

O script de atualização deve seguir esta rota:

  1. Usar app_id + app_secret para obter tenant_access_token
  2. Ler registros do Bitable
  3. Extrair tokens de anexo de vídeo e capa dos registros
  4. Chamar em lote batch_get_tmp_download_url
  5. Escrever em api/videos.json, api/covers.json, api/portfolio.json

Requisitos principais:

  • Suporte a paginação na leitura de registros
  • Solicitações em lote agrupadas em 5 tokens
  • Não codificar a lista de tokens no script
  • Priorizar geração dinâmica a partir de registros reais da tabela
  • Permitir múltiplas opções de nomes de campos

Nome de arquivo recomendado:

  • refresh.py

Priorize copiar diretamente o modelo incluso na skill:

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

Em seguida, apenas modifique o array de candidatos a campos; não codifique tokens ou URLs específicos.


Passo 7: Gerar Workflow do GitHub Actions

Não use mais launchd local como solução padrão.
A solução padrão deve ser GitHub Actions.

Requisitos do workflow:

  • Suporte a workflow_dispatch
  • Suporte a schedule, executando a cada 12 horas por padrão
  • Executar python refresh.py
  • Confirmar automaticamente api/videos.json, api/covers.json, api/portfolio.json

Secrets padrão:

  • LARK_APP_ID
  • LARK_APP_SECRET
  • LARK_BASE_TOKEN
  • LARK_TABLE_ID

Arquivo padrão:

  • .github/workflows/refresh.yml

Priorize copiar diretamente o modelo incluso na skill:

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

Passo 8: Configurar Secrets no Repositório

Se o ambiente atual já tiver esses valores e o usuário explicitamente permitir, configure diretamente:

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>

Em seguida, verifique:

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

Se faltar algum valor, pare aqui e informe claramente ao usuário qual está faltando; não invente.


Passo 9: Acionar Manualmente e Verificar Toda a Cadeia

Após concluir a configuração, execute o workflow manualmente imediatamente:

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

Em seguida, verifique o resultado online:

python3 - <<'PY'
import json, urllib.request, time
url = f'https://<domain-or-pages-url>/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

Em seguida, teste uma amostra de 1 vídeo:

  • Código de status deve ser 206 ou 200
  • content-type deve ser video/mp4 ou tipo de mídia reproduzível

Se o api/videos.json online ainda tiver um horário antigo:

  • Primeiro, verifique se a implantação do Pages foi concluída
  • Depois, verifique se o workflow realmente enviou o novo JSON
  • Então, confirme se a source do Pages está apontando para o branch e diretório corretos

Passo 10: Vínculo de Domínio

Se o usuário quiser um domínio personalizado, faça:

  • Arquivo CNAME
  • Configuração de domínio personalizado do GitHub Pages
  • Orientação de configuração de DNS

Esta parte segue o fluxo padrão do GitHub Pages, sem necessidade de acoplamento com a lógica do Feishu.


Explicação Padrão para o Usuário

Quando encontrar "o site abre, mas o vídeo não reproduz", priorize verificar:

  1. Se api/videos.json ainda está antigo
  2. Se o URL do Feishu dentro dele expirou
  3. Se o workflow de atualização automática falhou
  4. Se o Pages ainda não foi reimplantado

Por padrão, não suspeite primeiro do player nem do estilo front-end.

Se o usuário disser "a página está muito morta" ou "quero algo mais respirável como um portfólio", adicione uma camada de animação por padrão, em vez de apenas mudar cores e layout.


Critérios de Sucesso

Após a conclusão desta Skill, pelo menos deve atender:

  • Site está online
  • GitHub Pages está acessível
  • Vídeos podem ser reproduzidos
  • O repositório tem workflow de atualização automática
  • O repositório já tem 4 secrets LARK_*
  • Acionamento manual do workflow foi bem-sucedido
  • O _refreshed_at do api/videos.json online está com o novo horário

O Que Não Fazer por Padrão

  • Não gerar launchd local por padrão
  • Não depender do Mac do usuário ficar ligado por muito tempo por padrão
  • Não codificar todos os file_token
  • Não continuar apenas com a primeira tabela
  • Não gerar apenas videos.json, ignorando capas e registros estruturados

Implementação de Referência

Se precisar de uma abordagem já validada, primeiro reutilize diretamente os modelos do repositório da skill:

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

No projeto real, estes arquivos serão gerados no final:

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

Priorize reutilizar o padrão do repositório existente e, em seguida, adapte conforme o estilo do site do usuário.

Habilidades Relacionadas