Recentemente, experimentei muitas plataformas que permitem encadear etapas e compartilharei uma que me deixou animado: Reconhecimento Óptico de Caracteres para detectar texto em uma imagem e anexá-lo à postagem do Discourse!
Meu tópico de sandbox mostra como funciona: https://notes.maiki.interi.org/t/testing-ocr-calls/403
Fiz o primeiro no Pipedream e explicarei como fiz, seguindo as etapas. Há um recurso beta para compartilhar fluxos de trabalho nesse serviço, e o seguinte é compartilhado em https://pipedream.com/new?h=tch_3Z6fa9.
Embora isso possa ser um guia aprofundado sobre o uso do Pipedream com o Discourse, vou manter os detalhes leves, pois já saí dessa plataforma e compartilharei mais sobre isso mais tarde. 
Etapas
O esboço geral é: enviar o URL da imagem para a API Google Cloud Vision, executar os resultados pelo ChatGPT e, em seguida, anexar os resultados à postagem no Discourse.
Gatilho

Isso fornece um webhook para enviar dados. No Discourse, criei um webhook com duas configurações específicas:

O disparo apenas em Eventos de Postagem significa que meu tópico inicial não acionará o processo; isso é útil para mim, pois posso planejar usar tópicos como contêineres para aplicar funções externas (eu as chamo de “notas funcionais”).
O disparo apenas nessa tag significa que posso usar tags para controlar quais webhooks são produzidos por tópico; geralmente, eu teria apenas uma tag “funções”, para manter a lógica do processo simples.
O webhook envia uma carga útil com muitas informações, e usaremos os IDs do tópico e da postagem mais tarde no processo.
Fim baseado em condição
Esta é uma etapa para verificar se um motivo de edição está incluído. Se estiver, ele interrompe o fluxo de trabalho.
Na última etapa, atualizo a postagem e incluo um Motivo de Edição, e essa verificação garante que eu não continue atualizando a postagem… 
Uma das razões pelas quais parei de usar o Pipedream foi porque minhas verificações de webhook estavam consumindo créditos no serviço. Não acho que deveria pagar para processar condicionalmente um webhook, daí a mudança…
Extrair o URL da imagem
Decidi que, para este teste, cada postagem teria uma única imagem carregada nela. Esta etapa verifica o valor “cooked” e usa a seguinte expressão regular para capturar o URL:
/https?:\/\/[^\s"]+/
Chamada da API Google Cloud Vision
Esta é uma etapa de código personalizada no Pipedream. Os componentes pré-fabricados não faziam o que eu queria, e o serviço também tem um assistente de código que pode escrever código a partir de um prompt; como essas chamadas de API são diretas, foi fácil produzi-las com esse método.
Ele pega o valor da etapa anterior ({{steps.extract_by_regular_expression.$return_value[0].match}}), e este é o código:
import { axios } from "@pipedream/platform";
export default defineComponent({
props: {
imageUrl: {
type: "string",
label: "Image URL",
description: "URL of the image to be processed by Google Vision API",
},
apiKey: {
type: "string",
label: "API Key",
description: "Your Google Cloud API Key",
secret: true,
},
},
async run() {
const url = `https://vision.googleapis.com/v1/images:annotate?key=${this.apiKey}`;
const body = {
requests: [
{
image: {
source: {
imageUri: this.imageUrl,
},
},
features: [
{
type: "TEXT_DETECTION",
},
],
},
],
};
const config = {
method: "POST",
url,
data: body,
};
const response = await axios(this, config);
return response;
},
});
ChatGPT para edição
Pega a saída da etapa anterior ({{steps.google_cloud.$return_value.responses[0].fullTextAnnotation.text}}) e a passa como mensagem do Usuário. Para a mensagem do sistema, tenho:
Você está lendo a saída de uma API de visão que detectou texto em uma imagem. Revise a mensagem e edite-a para clareza. Retorne apenas o texto editado sem comentários.
Anexar à postagem no Discourse
Outra seção de código personalizada, pois as ações pré-fabricadas do Discourse no Pipedream cobrem apenas alguns cenários (criar um tópico ou uma postagem), e eu quero anexar o texto à postagem.
Primeiro, aqui está o código:
import { axios } from "@pipedream/platform";
export default defineComponent({
props: {
discourse: {
type: "app",
app: "discourse",
},
postId: {
type: "string",
label: "Post ID",
description: "The ID of the post to append text to",
},
text: {
type: "string",
label: "Text",
description: "The text to append to the post",
},
editReason: {
type: "string",
label: "Edit Reason",
description: "The reason for editing the post",
optional: true,
},
},
async run({ steps, $ }) {
const url = `https://${this.discourse.$auth.domain}/posts/${this.postId}.json`;
const response = await axios($, {
method: "GET",
url: url,
headers: {
"Api-Username": `${this.discourse.$auth.api_username}`,
"Api-Key": `${this.discourse.$auth.api_key}`,
},
});
const updatedText = `${response.raw} ${this.text}`;
return await axios($, {
method: "PUT",
url: url,
headers: {
"Api-Username": `${this.discourse.$auth.api_username}`,
"Api-Key": `${this.discourse.$auth.api_key}`,
},
data: {
post: {
raw: updatedText,
edit_reason: this.editReason,
},
},
});
},
});
Essas propriedades para a etapa são preenchidas assim:
ID da Postagem
Captura o ID da postagem da carga útil original: {{steps.trigger.event.body.post.id}}
Isso é usado para editar essa postagem diretamente.
Texto
---
<blockquote>
{{steps.chat.$return_value.generated_message.content}}
</blockquote>
[details="Texto detectado"]
{{steps.google_cloud.$return_value.responses[0].textAnnotations[0].description}}
[/details]
Basicamente, quero adicionar uma linha horizontal abaixo de cada imagem, com uma citação de texto editado e os detalhes para verificar a saída bruta.
Como cada postagem terá uma imagem, isso funciona muito facilmente. Pergunto-me como fazer isso com várias imagens ao mesmo tempo? 
Motivo da Edição
Detecção de Texto OCR
Isso é adicionado como o motivo da edição para a atualização da postagem, o que evitará um loop de atualização da postagem devido à etapa no início.

Acho super útil incluir sempre um motivo de edição, especialmente ao lidar com serviços externos.
E é isso! Como você pode ver no meu sandbox, funciona muito bem!
Tenho uma viagem chegando e planejo refinar a edição da OpenAI para também traduzir para o inglês, se necessário, essa é uma opção que eu teria adicionado ao prompt do sistema para este fluxo de trabalho.