hospital-devolucion-gmail-intake

star 0

Watches a Gmail inbox with `gogcli` for EPS→IPS glosa notifications, classifies emails as glosa batches, downloads Excel/CSV attachments, and creates a `hospital_devolucion_batch` task in Salmona with the file attached. Use it when the hospital wants to automatically process incoming glosas sent by an EPS via email, configure the devolucion watcher, or reprocess a glosa email that was missed.

arkangelai By arkangelai schedule Updated 5/13/2026

name: hospital-devolucion-gmail-intake description: Watches a Gmail inbox with gogcli for EPS→IPS glosa notifications, classifies emails as glosa batches, downloads Excel/CSV attachments, and creates a hospital_devolucion_batch task in Salmona with the file attached. Use it when the hospital wants to automatically process incoming glosas sent by an EPS via email, configure the devolucion watcher, or reprocess a glosa email that was missed. version: 1.0.0 author: claudio@arkangel.ai platforms: [macos, linux] metadata: hermes: tags: [medical, hospital, glosa, devolucion, gmail, intake, colombia, ips] category: medical-insurance-audit requires_toolsets: [terminal] required_environment_variables:

  • name: GOGCLI_CREDENTIALS_PATH prompt: Path to the gogcli OAuth credentials help: Generate with gogcli auth init using a Google account with access to the hospital inbox. Same credentials as medical-invoice-gmail-intake if sharing a single inbox. required_for: full functionality
  • name: GMAIL_DEVOLUCION_LABEL prompt: Gmail label to watch for incoming glosas (e.g. "glosas" or "devolucion") help: Create a dedicated label in Gmail and configure a filter so EPS glosa emails land there. Avoid watching INBOX directly to prevent mixing with audit-side emails. required_for: full functionality
  • name: SALMONA_API_URL prompt: Base URL of the Salmona API (e.g. https://salmona.arkangel.ai) required_for: full functionality
  • name: SALMONA_API_KEY prompt: Salmona API key with agent role help: Generate via Salmona settings. Must have permission to create tasks at queued status. required_for: full functionality

hospital-devolucion-gmail-intake

First skill in the hospital devolucion pipeline. It listens on a Gmail label for incoming glosa notifications from EPSs, downloads the attached Excel or CSV files, and creates a hospital_devolucion_batch task in Salmona. The batch task then spawns one hospital_devolucion child task per glosa group for analysis by hospital-devolucion-audit.

Flow position: Gmail → this skill → hospital_devolucion_batch (Salmona) → hospital_devolucion × N → hospital-devolucion-audit

When to Use

  • The IPS wants to start/configure the Gmail watcher for incoming glosas.
  • A new email arrives in the $GMAIL_DEVOLUCION_LABEL label with an Excel attachment containing glosa line items and must be filed.
  • An email landed in hospital-devolucion/error and needs to be reprocessed manually.
  • The user asks "¿cómo entra una glosa de la EPS al sistema?" or "¿el correo de Sura ya fue procesado?".

Do not use: if the email has no Excel or CSV attachment; if it already has label hospital-devolucion/intake (avoid double processing); if the attachment looks like a regular invoice for EPS audit (use medical-invoice-gmail-intake instead).

Distinction from medical-invoice-gmail-intake: that skill handles invoices sent by IPS to EPS (aseguradora perspective). This skill handles glosas sent by EPS to IPS (hospital/prestador perspective). The email direction, task type, and context schema are completely different.

Input Contract

Trigger: Gmail message arrival on label $GMAIL_DEVOLUCION_LABEL
         OR explicit call with a specific message_id for reprocessing

No structured JSON input required. The skill reads directly from Gmail using gogcli.

Output Contract

On success, the skill creates a hospital_devolucion_batch task in Salmona. The task carries:

  • Context — batch metadata (see schema below).
  • Input files — the Excel/CSV attachment uploaded to the task so the batch agent can read it.

Batch context schema:

Field Type Description
batch_id string BATCH-YYYYMMDD-XXXXX generated by this skill
documentos string[] Names of all uploaded attachments
pagador_nombre string | null Payer name extracted from email or Excel; null if not found
email_origen string From address of the triggering email
email_subject string Subject line of the triggering email
message_id string Gmail message ID for traceability

The skill returns:

{
  "batch_task_id": "<salmona-task-id>",
  "message_id": "<gmail-message-id>",
  "label_aplicado": "hospital-devolucion/intake",
  "archivos_radicados": [
    { "name": "glosas_mayo.xlsx", "sha256": "<hex>" }
  ],
  "pagador_detectado": "EPS Sura"
}

On non-glosa emails: { "label_aplicado": "hospital-devolucion/not-applicable" } and stops. On failure: { "label_aplicado": "hospital-devolucion/error", "motivo": "<string>" } and stops.

Procedure

  1. Verify tools and credentials.

    gogcli --version
    test -f "$GOGCLI_CREDENTIALS_PATH" || { echo "Missing gogcli creds"; exit 1; }
    
  2. Start the watcher (or process a specific message).

    • Real-time push watcher:
      gogcli watch start --label "$GMAIL_DEVOLUCION_LABEL" --topic hospital-devolucion-intake
      
    • Polling (fallback): list unprocessed messages.
      gogcli messages list \
        --label "$GMAIL_DEVOLUCION_LABEL" \
        --query "-label:hospital-devolucion/intake -label:hospital-devolucion/not-applicable -label:hospital-devolucion/error has:attachment"
      
    • Reprocess a specific message:
      gogcli messages get "$MESSAGE_ID" --format full
      
  3. Classify the email — is it a glosa batch?

    Positive signals (at least 2 must match):

    • Subject contains: glosa, glosas, devolución técnica, devolucion tecnica, notificación glosa, respuesta glosa, objetación, or a glosa/document number pattern.
    • Sender domain matches a known EPS (sura.com.co, compensar.com, sanitas.com.co, famisanar.com, etc.).
    • At least one attachment is an Excel (.xlsx, .xls) or CSV whose filename or first-row headers suggest glosa data (columns like CUPS, causal, valor_glosado, num_glosa, num_documento).

    If it does not match → apply label hospital-devolucion/not-applicable and stop:

    gogcli messages modify "$MESSAGE_ID" --add-label hospital-devolucion/not-applicable
    
  4. Check for duplicate (idempotency). Before creating a task, verify no hospital_devolucion_batch task already exists with context.message_id = "$MESSAGE_ID":

    curl -s -H "Authorization: Bearer $SALMONA_API_KEY" \
      "$SALMONA_API_URL/api/tasks?task_type=hospital_devolucion_batch&limit=50" \
      | jq --arg mid "$MESSAGE_ID" '.data[] | select(.context.message_id == $mid) | .id'
    

    If a task is found → apply label hospital-devolucion/intake (if not already present) and stop.

  5. Download Excel/CSV attachments.

    WORK_DIR="/tmp/devolucion-intake/$MESSAGE_ID"
    mkdir -p "$WORK_DIR"
    gogcli messages attachments download "$MESSAGE_ID" \
      --filter "*.xlsx,*.xls,*.csv" \
      --out "$WORK_DIR"
    

    If no Excel/CSV found → apply label hospital-devolucion/error with motivo: "no_excel_attachment" and stop.

  6. Extract payer name (best-effort). Try in order:

    • First row/header of the Excel for a "pagador", "EPS", or "aseguradora" column.
    • Sender display name or domain (map known EPS domains to nombres).
    • Subject line keywords.
    • If nothing found → pagador_nombre: null (acceptable).
  7. For each Excel/CSV attachment, create a Salmona batch task.

    Generate a fresh batch_id for each file so each task is independently traceable:

    DATE=$(TZ=America/Bogota date +%Y%m%d)
    SUFFIX=$(tr -dc 'A-Z0-9' </dev/urandom | head -c 5)
    BATCH_ID="BATCH-${DATE}-${SUFFIX}"
    

    a. Set the batch description. Per issue arkangelai/salmona-api#210, the skills repo is the canonical home for agent prompts. The task description is a thin pointer to the skill that processes the envelope (hospital-devolucion-batch-parse), not an inlined prompt:

    DESCRIPTION="Run skill hospital-devolucion-batch-parse on the attached Excel/CSV. Each row becomes one hospital_devolucion task (one glosa = one item)."
    DESCRIPTION_JSON=$(jq -n --arg d "$DESCRIPTION" '$d')
    

    b. Create the batch task (agent role allows status: queued directly):

    PAYLOAD=$(jq -n \
      --arg title "Lote glosas — ${PAGADOR_NOMBRE:-Email ${MESSAGE_ID}}" \
      --argjson description "$DESCRIPTION_JSON" \
      --arg batch_id "$BATCH_ID" \
      --arg filename "$FILENAME" \
      --argjson pagador_nombre "$PAGADOR_JSON" \
      --arg email_origen "$FROM_ADDRESS" \
      --arg email_subject "$SUBJECT" \
      --arg message_id "$MESSAGE_ID" \
      '{
        title: $title,
        description: $description,
        task_type: "hospital_devolucion_batch",
        priority: "medium",
        context: {
          batch_id: $batch_id,
          documentos: [$filename],
          pagador_nombre: $pagador_nombre,
          email_origen: $email_origen,
          email_subject: $email_subject,
          message_id: $message_id
        }
      }')
    TASK=$(curl -s -X POST \
      -H "Authorization: Bearer $SALMONA_API_KEY" \
      -H "Content-Type: application/json" \
      -d "$PAYLOAD" \
      "$SALMONA_API_URL/api/tasks")
    TASK_ID=$(echo "$TASK" | jq -r '.data.id')
    

    c. Upload the Excel file as a task input:

    curl -s -X POST \
      -H "Authorization: Bearer $SALMONA_API_KEY" \
      -F "file=@$WORK_DIR/$FILENAME" \
      -F "description=$FILENAME" \
      -F "local_path=/hospitales/devolucion/$BATCH_ID/$FILENAME" \
      "$SALMONA_API_URL/api/tasks/$TASK_ID/inputs/upload"
    

    d. Queue the task:

    curl -s -X PATCH \
      -H "Authorization: Bearer $SALMONA_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"status": "queued"}' \
      "$SALMONA_API_URL/api/tasks/$TASK_ID/status"
    
  8. Label the email and ACK.

    gogcli messages modify "$MESSAGE_ID" \
      --add-label hospital-devolucion/intake \
      --add-label "hospital-devolucion/batch-$BATCH_ID"
    
    gogcli messages reply "$MESSAGE_ID" \
      --body "ACK — Glosas recibidas y registradas. Lote: $BATCH_ID. task_id: $TASK_ID. Procesaremos y responderemos dentro del plazo."
    
  9. Clean up temp files.

    rm -rf "$WORK_DIR"
    
  10. Return output payload.

    {
      "batch_task_id": "<task-id>",
      "message_id": "<gmail-message-id>",
      "label_aplicado": "hospital-devolucion/intake",
      "archivos_radicados": [
        { "name": "glosas_mayo.xlsx", "sha256": "<hex>" }
      ],
      "pagador_detectado": "EPS Sura"
    }
    

Pitfalls

  • Mixed inbox with medical-invoice-gmail-intake: if both skills watch the same inbox, an EPS glosa email might match both classifiers. Use a dedicated $GMAIL_DEVOLUCION_LABEL (e.g. a Gmail filter that routes emails from known EPS domains with "glosa" in subject) to prevent overlap.
  • Excel with merged cells or multi-header rows: the batch agent handles this, but record the raw filename without trying to parse the Excel here — just download and upload it.
  • Multiple Excel files in one email: create one batch task per file, each with its own batch_id. The for-loop in step 8 handles this — do not merge attachments.
  • EPS sends a ZIP with the Excel inside: unzip first:
    unzip -o "$WORK_DIR/$ZIP_FILE" -d "$WORK_DIR"
    
    Then treat the extracted .xlsx as the attachment.
  • gogcli fails with invalid_grant: OAuth token expired. Run gogcli auth refresh or regenerate with gogcli auth init.
  • Salmona returns 422 status must be queued: the API key does not have agent role. Verify the key was generated for the Salmona agent account (app_metadata.role = "agent").
  • Duplicate on retry: the idempotency check in step 4 (filter by context.message_id) prevents double-filing. Always run it before creating a task.

Verification

  • After running the skill, the email has exactly one of the labels hospital-devolucion/{intake|not-applicable|error}.
  • A hospital_devolucion_batch task exists in Salmona with context.message_id matching the processed email.
  • The task has at least one input file (the Excel attachment).
  • The task status is queued.
  • The Gmail thread has an ACK reply containing the batch_id and task_id.
  • No duplicate batch task exists for the same message_id.

References

Install via CLI
npx skills add https://github.com/arkangelai/skills --skill hospital-devolucion-gmail-intake
Repository Details
star Stars 0
call_split Forks 2
navigation Branch main
article Path SKILL.md
More from Creator