Experimenté mucho recientemente con varias plataformas que permiten encadenar pasos, y compartiré una que me entusiasmó: Reconocimiento Óptico de Caracteres para detectar texto en una imagen y agregarlo a la publicación de Discourse.
Mi tema de prueba muestra cómo funciona: https://notes.maiki.interi.org/t/testing-ocr-calls/403
Hice el primero en Pipedream y explicaré cómo lo hice siguiendo los pasos. Hay una función beta para compartir flujos de trabajo en ese servicio, y lo siguiente se comparte en https://pipedream.com/new?h=tch_3Z6fa9.
Si bien esto sería una guía detallada para usar Pipedream con Discourse, seré breve en los detalles, ya que ya he dejado esa plataforma y compartiré más sobre eso más adelante. 
Pasos
El esquema general es: enviar la URL de la imagen a la API de Google Cloud Vision, procesar los resultados a través de ChatGPT y luego agregar los resultados a la publicación en Discourse.
Disparador

Esto proporciona un webhook para enviar datos. En Discourse creé un webhook con dos configuraciones específicas:

Solo se activa en Eventos de Publicación significa que mi tema inicial no activará el proceso; esto es útil para mí, ya que puedo planificar usar temas como contenedores para aplicar funciones externas (las llamo “notas funcionales”).
Solo se activa en esa etiqueta significa que puedo usar etiquetas para controlar qué webhooks se producen por tema; en general, solo tendría una etiqueta de “funciones” para mantener la lógica del proceso simple.
El webhook envía una carga útil con mucha información, y usaremos los IDs del tema y la publicación más adelante en el proceso.
Fin basado en condición
Este es un paso para verificar si se incluye una razón de edición. Si es así, detiene el flujo de trabajo.
En el último paso actualizo la publicación e incluyo una Razón de Edición, y esta verificación asegura que no siga actualizando la publicación… 
Una de las razones por las que dejé de usar Pipedream fue porque mis verificaciones de webhook consumían créditos en el servicio. No creo que deba pagar para procesar condicionalmente un webhook, por lo tanto, sigo adelante…
Extraer la URL de la imagen
Decidí que para esta prueba cada publicación tendría una sola imagen cargada. Este paso verifica el valor “cocinado” y utiliza la siguiente expresión regular para obtener la URL:
/https?:\/\/[^\s\"]+/
Llamada a la API de Google Cloud Vision
Este es un paso de código personalizado en Pipedream. Los componentes prefabricados no hacían lo que quería, y el servicio también tiene un asistente de código que puede escribir código a partir de una indicación; como estas llamadas a la API son sencillas, fue fácil producirlas de esta manera.
Toma el valor del paso anterior ({{steps.extract_by_regular_expression.$return_value[0].match}}), y este es el 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 editar
Toma la salida del paso anterior ({{steps.google_cloud.$return_value.responses[0].fullTextAnnotation.text}}) y la pasa como mensaje del usuario. Para el mensaje del sistema tengo:
Eres el lector de la salida de una API de visión que detectó texto en una imagen. Revisa el mensaje y edítalo para mayor claridad. Devuelve solo el texto editado sin comentarios.
Agregar a la publicación en Discourse
Otra sección de código personalizado, ya que las acciones de Discourse prefabricadas en Pipedream solo cubren un par de escenarios (crear un tema o una publicación), y quiero agregar el texto a la publicación.
Primero, aquí está el 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,
},
},
});
},
});
Esas propiedades para el paso se completan de la siguiente manera:
ID de publicación
Obtiene el ID de la publicación de la carga útil original: {{steps.trigger.event.body.post.id}}
Esto se usa para editar esa publicación directamente.
Texto
---
<blockquote>
{{steps.chat.$return_value.generated_message.content}}
</blockquote>
[details="Texto detectado"]
{{steps.google_cloud.$return_value.responses[0].textAnnotations[0].description}}
[/details]
Básicamente, quiero agregar una regla horizontal debajo de cada imagen, con una cita de texto editado y los detalles para verificar la salida sin procesar.
Dado que cada publicación tendrá una imagen, esto funciona muy fácilmente. Me pregunto cómo hacerlo con varias imágenes a la vez. 
Razón de edición
Detección de texto OCR
Esto se agrega como la razón de edición para la actualización de la publicación, lo que evitará un bucle de actualización de publicación debido al paso al principio.

Me resulta muy útil incluir siempre una razón de edición, especialmente cuando se trata de servicios externos.
¡Y eso es todo! Como puedes ver en mi sandbox, ¡funciona bastante bien!
Tengo un viaje próximamente y planeo ajustar la edición de OpenAI para que también traduzca al inglés si es necesario, esa es una opción que habría agregado a la indicación del sistema para este flujo de trabajo.