Hoy vamos a aprender cómo podemos crear un webhook para qué nos avise EAS Expo React Native cada vez que realice un build. Además lo integraremos con n8n para crear un flujo que permitirá enviar una alerta a Discord con los datos del build realizado.

Lo primero que haremos es instalar n8n si no lo tenemos.
Crear un webhook en n8n
Abre n8n y crea un nuevo workflow.
Añade un nodo Webhook:

Método: POST
Path: expo-build
Authentication: None
Configurar un Webhook en Expo con eas-cli
Para configurar un webhook que se active al finalizar un build, sigue estos pasos:
- Instala
eas-cli
si aún no lo tienes:
npm install -g eas-cli
Ejecuta el siguiente comando en la raíz de tu proyecto Expo:
eas webhook:create --event BUILD --url https://n8n.tudominio.com/webhook/expo-build --secret TU_SECRETO_WEBHOOK
*Puede ser –event -> BUILD / SUBMIT
Reemplaza https://n8n.tudominio.com/webhook/expo-build con la URL de tu webhook en n8n. (Se puede copiar desde el propio webhook) Usa la que no pone -test.
Reemplaza TU_SECRETO_WEBHOOK
por algo como miexposecretoseguro123
. Debe ser de al menos 16 caracteres y maximo 1000.
Este comando te permitirá configurar el webhook para que Expo envíe una notificación POST a la URL especificada cada vez que un build finalice.
Verifica que el webhook esté registrado correctamente:
eas webhook:list
Este comando mostrará una lista de los webhooks configurados para tu proyecto, permitiéndote confirmar que el nuevo webhook está activo.
Aquí tenemos más información sobre lo que se puede hacer con webhooks: https://docs.expo.dev/eas/webhooks/
Primero debemos probar el webhook, para que no nos de error el siguiente paso. Desde un terminal de bash ponemos:
curl -X POST https://n8n.tudominio.com/webhook/expo-build -H 'Contype: application/json' -d '{"mensaje": "¡Hola desde mi primer flujo n8n!"}'
Procesar el JSON
Añade un nodo Edit Fields Set para dejar los datos que quieras usar:
Por ejemplo:
{ "status": "{{ $json.body.status }}", "platform": "{{ $json.body.platform }}", "buildUrl": "{{ $json.body.artifacts.buildUrl }}", "detailsUrl": "{{ $json.body.buildDetailsPageUrl }}", "appName": "{{ $json.body.metadata.appName }}", "version": "{{ $json.body.metadata.appVersion }}", "message": "{{ $json.body.metadata.message }}", "statusEmoji": "{{ $json.body.status === 'finished' ? '✅' : $json.body.status === 'errored' ? '❌' : '⚠️'}}" }
Nodo para enviar mensaje a Discord
Obtener el Webhook de Discord
Primero, necesitas configurar un webhook en Discord para poder enviar mensajes desde n8n.
- Abre Discord y ve a tu servidor.
- En la barra lateral de tu servidor, haz clic en el canal donde quieres que se publique el mensaje.
- Haz clic en el icono del engranaje al lado del nombre del canal para abrir Configuración del Canal.
- Ve a la sección Integraciones y haz clic en Webhooks.
- Haz clic en Crear Webhook.
- Copia la URL del Webhook, la necesitarás en n8n.
Configurar el nodo «HTTP Request» en n8n
Una vez que tengas la URL del webhook, podemos configurar n8n para enviar los datos a Discord.

- Agrega un nodo «HTTP Request» en n8n:
- Haz clic en el botón «+» en el lienzo de trabajo.
- Busca «HTTP Request» y selecciónalo.
- Configura el nodo «HTTP Request»:
- Método: Selecciona POST.
- URL: Pega la URL del Webhook de Discord que copiaste previamente.
- Encabezados:
- Añade un encabezado
Content-Type
con valorapplication/json
.
- Añade un encabezado
- Body Parameters:
- Selecciona JSON como tipo de cuerpo.
- En el cuerpo JSON, agrega la estructura para el mensaje. Por ejemplo:
{ "content": "**{{$json["statusEmoji"]}} {{ $json.appName }} ({{ $json.version }}) [{{ $json.platform }}] Build {{$json["status"]}}**", "embeds": [ { "title": "{{$json["appName"]}} (v{{$json["version"]}})", "description": "Plataforma: {{$json["platform"]}}\nMensaje: {{$json["message"]}}", "url": "{{$json["detailsUrl"]}}", "color": {{$json["status"] === 'finished' ? 3066993 : 15158332}}, "fields": [ { "name": "Build URL", "value": "{{$json["buildUrl"]}}" } ], "timestamp": "{{new Date().toISOString()}}" } ] }
Para testearlo debemos hacer esto:
Primero copiamos el JSON de ejemplo que viene en la web de expo EAS:
- Para BUILDS
{ "id": "147a3212-49fd-446f-b4e3-a6519acf264a", "accountName": "dsokal", "projectName": "example", "buildDetailsPageUrl": "https://expo.dev/accounts/dsokal/projects/example/builds/147a3212-49fd-446f-b4e3-a6519acf264a", "parentBuildId": "75ac0be7-0d90-46d5-80ec-9423fa0aaa6b", "appId": "bc0a82de-65a5-4497-ad86-54ff1f53edf7", "initiatingUserId": "d1041496-1a59-423a-8caf-479bb978203a", "cancelingUserId": null, "platform": "android", "status": "finished", "artifacts": { "buildUrl": "https://expo.dev/artifacts/eas/wyodu9tua2ZuKKiaJ1Nbkn.aab", "logsS3KeyPrefix": "production/f9609423-5072-4ea2-a0a5-c345eedf2c2a" }, "metadata": { "appName": "example", "username": "dsokal", "workflow": "managed", "appVersion": "1.0.2", "appBuildVersion": "123", "cliVersion": "0.37.0", "sdkVersion": "41.0.0", "buildProfile": "production", "distribution": "store", "appIdentifier": "com.expo.example", "gitCommitHash": "564b61ebdd403d28b5dc616a12ce160b91585b5b", "gitCommitMessage": "Add home screen", "runtimeVersion": "1.0.2", "channel": "default", // available for EAS Update "releaseChannel": "default", "reactNativeVersion": "0.60.0", "trackingContext": { "platform": "android", "account_id": "7c34cbf1-efd4-4964-84a1-c13ed297aaf9", "dev_client": false, "project_id": "bc0a82de-65a5-4497-ad86-54ff1f53edf7", "tracking_id": "a3fdefa7-d129-42f2-9432-912050ab0f10", "project_type": "managed", "dev_client_version": "0.6.2" }, "credentialsSource": "remote", "isGitWorkingTreeDirty": false, "message": "release build", "runFromCI": false }, "metrics": { "memory": 895070208, "buildEndTimestamp": 1637747861168, "totalDiskReadBytes": 692224, "buildStartTimestamp": 1637747834445, "totalDiskWriteBytes": 14409728, "cpuActiveMilliseconds": 12117.540078, "buildEnqueuedTimestamp": 1637747792476, "totalNetworkEgressBytes": 355352, "totalNetworkIngressBytes": 78781667 }, "error": { "message": "Unknown error. Please see logs.", "errorCode": "UNKNOWN_ERROR" }, "createdAt": "2021-11-24T09:53:01.155Z", "enqueuedAt": "2021-11-24T09:53:01.155Z", "provisioningStartedAt": "2021-11-24T09:54:01.155Z", "workerStartedAt": "2021-11-24T09:54:11.155Z", "completedAt": "2021-11-24T09:57:42.715Z", "updatedAt": "2021-11-24T09:57:42.715Z", "expirationDate": "2021-12-24T09:53:01.155Z", "priority": "high", // or: "normal", "low" "resourceClass": "android-n2-1.3-12", "actualResourceClass": "android-n2-1.3-12", "maxRetryTimeMinutes": 3600 }
Puedes cambiar este parametro:
«status»: «finished», a «errored» o «canceled»
Para SUBMITS
{ "id": "0374430d-7776-44ad-be7d-8513629adc54", "accountName": "dsokal", "projectName": "example", "submissionDetailsPageUrl": "https://expo.dev/accounts/dsokal/projects/example/builds/0374430d-7776-44ad-be7d-8513629adc54", "parentSubmissionId": "75ac0be7-0d90-46d5-80ec-9423fa0aaa6b", "appId": "23c0e405-d282-4399-b280-5689c3e1ea85", "archiveUrl": "http://archive.url/abc.apk", "initiatingUserId": "7bee4c21-3eaa-4011-a0fd-3678b6537f47", "cancelingUserId": null, // available for canceled submissions "turtleBuildId": "8c84111e-6d39-449c-9895-071d85fd3e61", "platform": "android", "status": "errored", "submissionInfo": { // available for failed submissions "error": { "message": "Android version code needs to be updated", "errorCode": "SUBMISSION_SERVICE_ANDROID_OLD_VERSION_CODE_ERROR" }, "logsUrl": "https://submission-service-logs.s3-us-west-1.amazonaws.com/production/submission_728aa20b-f7a9-4da7-9b64-39911d427b19.txt" }, "createdAt": "2021-11-24T10:15:32.822Z", "updatedAt": "2021-11-24T10:17:32.822Z", "completedAt": "2021-11-24T10:17:32.822Z", "maxRetryTimeMinutes": 3600 }
Creamos en nuevo archivo llamado payload.json y metemos el contenido dentro:
vi payload.json
Guardamos el archivo y ejecutamos el siguiente comando:
curl -X POST https://auto.quierolibros.com/webhook/expo-build \ -H "Content-Type: application/json" \ --data-binary "@payload.json"

Ingeniero en Informática, Investigador, me encanta crear cosas o arreglarlas y darles una nueva vida. Escritor y poeta. Más de 20 APPs publicadas y un libro en Amazon.