Pular para o conteúdo
Development

Adicionando busca de imagens do Pexels ao meu gerenciador de blog

Por Victor Da Luz
railsrubypexelsdev-logblog-manager

O Medium quer uma imagem de cabeçalho. Meu gerenciador de blog precisava de uma forma de escolher uma sem sair do app.

Venho construindo um app em Rails que me ajuda a sindicar posts do meu blog em Astro pro Medium e pro LinkedIn. O fluxo de cross-posting já estava quase pronto; eu conseguia escanear um repositório do GitHub em busca de arquivos markdown, renderizá-los como HTML, e enviá-los ao Medium como rascunhos. Mas faltava uma peça: o Medium destaca uma imagem de cabeçalho no topo de todo post, e meu app não tinha como selecionar uma.

A escolha óbvia foi o Pexels. Eles têm uma API limpa, um plano gratuito generoso, e uma exigência de atribuição fácil de satisfazer com um <figcaption>.

O que eu construí

A seção do Pexels fica na página de detalhe do post. Há um formulário de busca pré-preenchido com o título do post, uma grade de resultados que carrega sem recarregar a página inteira, e um botão “Selecionar” por imagem. Quando você escolhe uma, o card do post atualiza no lugar e o botão de import pro Medium ativa.

A abordagem com Turbo Frame deixou isso direto. O formulário de busca mira num turbo_frame_tag "pexels_results", então a resposta substitui só aquela região da página:

<%= form_with url: search_pexels_post_path(post), method: :get,
      data: { turbo_frame: "pexels_results" } do |f| %>
  <%= f.text_field :query, value: post.title.presence || post.slug %>
  <%= f.submit "Search" %>
<% end %>

<%= turbo_frame_tag "pexels_results" %>

No lado do controller, search_pexels renderiza o partial direto dentro do frame. Rápido, sem transição de página, sem reset de scroll.

A pegadinha de autenticação do Pexels

Toda outra API que integrei usa Authorization: Bearer {token}. O Pexels não. O cabeçalho de autenticação deles é só a chave de API crua:

req["Authorization"] = @api_key   # correct
req["Authorization"] = "Bearer #{@api_key}"  # wrong - 401

Está documentado, mas é fácil passar batido quando você copia de outro client.

Onde guardar a chave de API

Por blog vs. global: eu tenho uma conta só no Pexels, então por blog significaria digitar a mesma chave várias vezes. Adicionei um model singleton AppSetting no lugar:

class AppSetting < ApplicationRecord
  encrypts :pexels_api_key

  def self.current
    first_or_create!
  end
end

O Active Record Encryption (já usado pros tokens do GitHub e do Medium) cuida da criptografia em repouso. A página de configurações em /settings me dá uma UI pra colar a chave sem tocar no credentials.yml.enc.

Bloqueando o import pro Medium

O botão de import pro Medium agora exige que uma imagem do Pexels esteja selecionada. A checagem vive tanto na view (tooltip desabilitado) quanto no controller (redirect com alerta); bloqueios só de view são contornados com um POST direto.

Quando o DraftCreator roda

O DraftCreator antepõe a imagem selecionada como um <figure> antes do corpo HTML do post. O <figcaption> inclui a atribuição do fotógrafo, satisfazendo as exigências do Pexels. O Medium renderiza isso no topo do rascunho.

Uma pegadinha de teste

O minitest/mock foi removido no Minitest 6.0.6; Minitest::Mock não existe mais. Descartei o teste de controller baseado em stub e passei a depender só dos testes unitários de Pexels::Client diretamente.

O que vem a seguir

A ação search_pexels ainda lê de Rails.application.credentials; conectá-la a AppSetting.current.pexels_api_key é o desdobramento óbvio de uma linha só. Depois disso: cross-posting pro LinkedIn, que já tem o token mas não tem o job.

Leitura relacionada

Você também pode achar útil

AdGuard

AdGuard para iOS

Bloqueio de anúncios e rastreadores em todo o sistema no iOS, sem necessidade de um servidor DNS separado.

Como afiliado da AdGuard, ganho com compras qualificadas.

Saiba mais
Proton

Proton Mail

E-mail criptografado de ponta a ponta, com arquitetura de acesso zero.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais
Proton

Proton Drive

Armazenamento em nuvem criptografado, da equipe por trás do Proton Mail.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais