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.htmlou página front-end estáticaapi/videos.jsonapi/covers.jsonapi/portfolio.jsonrefresh.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:
- Ler os registros mais recentes da tabela multidimensional do Feishu
- Chamar a API do Feishu para resolver o
file_tokendo anexo em um URL temporário - Gerar
api/*.json - Enviar de volta para o repositório GitHub
- 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_IDLARK_APP_SECRETLARK_BASE_TOKENLARK_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 obrasapi/videos.json:video_token -> tmp_download_urlapi/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
requestAnimationFrameapenas 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.jsone/api/covers.json - Ou busca
/api/portfolio.jsondiretamente 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
cnameestá normal (se houver domínio personalizado)- source aponta para
maine o diretório raiz
Passo 6: Gerar Script de Atualização Automática
O script de atualização deve seguir esta rota:
- Usar
app_id + app_secretpara obtertenant_access_token - Ler registros do Bitable
- Extrair tokens de anexo de vídeo e capa dos registros
- Chamar em lote
batch_get_tmp_download_url - 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_IDLARK_APP_SECRETLARK_BASE_TOKENLARK_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
206ou200 content-typedeve servideo/mp4ou 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:
- Se
api/videos.jsonainda está antigo - Se o URL do Feishu dentro dele expirou
- Se o workflow de atualização automática falhou
- 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_atdoapi/videos.jsononline está com o novo horário
O Que Não Fazer por Padrão
- Não gerar
launchdlocal 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.pyassets/refresh.ymlassets/portfolio.sample.json
No projeto real, estes arquivos serão gerados no final:
refresh.py.github/workflows/refresh.ymlapi/videos.jsonapi/covers.jsonapi/portfolio.json
Priorize reutilizar o padrão do repositório existente e, em seguida, adapte conforme o estilo do site do usuário.