Skip to main content

Slack API via slackHandler.php

Use this Skill to interact with Slack through the existing PHP helper at scripts/slackHandler.php. It wraps Slack Web API methods such as conversations.replies, chat.postMessage, files.upload, and related helpers. Use when a request involves Slack threads, channel posts, uploads, or deleting Slack content from PLA.

Prerequisites

  • Ensure SLACK_BOT_TOKEN is set in .env or the environment; the handler loads it automatically.
  • Run commands from the pla-cli root; PHP 8.1+ is already used in the project.
  • The bot must belong to the target channel; the handler will attempt conversations.join automatically but surface errors if it cannot.

Quick commands (run from pla-cli/)

  • Read a thread (formatted JSON):
    php scripts/slackHandler.php https://workspace.slack.com/archives/C1234567890/p1234567890123456
  • Raw API payload:
    php scripts/slackHandler.php https://workspace.slack.com/archives/C1234567890/p1234567890123456 --raw
  • Post a channel message (plain text): php -r "require 'scripts/slackHandler.php'; $h=new SlackHandler(); echo json_encode($h->postMessage('C1234567890','Hola desde PLA'), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);"
  • Post with Block Kit (4th param = blocks array, 1st text param = fallback): php -r "require 'scripts/slackHandler.php'; $h=new SlackHandler(); $blocks=[['type'=>'header','text'=>['type'=>'plain_text','text'=>'Title']],['type'=>'section','text'=>['type'=>'mrkdwn','text'=>'Body text']]]; echo json_encode($h->postMessage('C1234567890','Fallback text',null,$blocks), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);"
  • Reply inside a thread: php -r "require 'scripts/slackHandler.php'; $h=new SlackHandler(); echo json_encode($h->postMessage('C1234567890','Respuesta en thread','1712345678.987654'), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);"
  • Upload a local file:
    php -r "require 'scripts/slackHandler.php'; $u=new SlackFileUploader(); echo json_encode($u->upload('C1234567890','/abs/path/report.pdf', null, 'Subiendo reporte'), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);"
  • Upload inline content as a file:
    php -r "require 'scripts/slackHandler.php'; $u=new SlackFileUploader(); echo json_encode($u->uploadFromString('C1234567890','contenido','nota.txt','Nota generada'), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);"
  • Delete a message:
    php -r "require 'scripts/slackHandler.php'; $h=new SlackHandler(); echo json_encode($h->deleteMessage('C1234567890','1712345678.987654'), JSON_PRETTY_PRINT);"
  • Delete an uploaded file:
    php -r "require 'scripts/slackHandler.php'; $u=new SlackFileUploader(); echo json_encode($u->deleteFile('F123ABC456'), JSON_PRETTY_PRINT);"

Tips

  • Thread URLs are auto-parsed; no need to extract channel or ts.
  • For large channels, conversations.replies paginates via next_cursor; the handler loops until completion.
  • Respect Slack rate limits; repeated thread fetches or uploads in bursts may be throttled.
  • Prefer channel IDs (C…, G…, D…) instead of names; chat.postMessage will error on unknown targets.

Block Kit: mensajes bien formados

IMPORTANT: postMessage() supports blocks natively via the 4th parameter. Always pass a plain text as fallback (Slack requires it for notifications/accessibility). Signature: postMessage(channel, text, threadTs, blocks).

  • Siempre usa un array blocks (orden visual). Recomienda: headersectionactionscontextdivider según necesidad.
  • Texto: mrkdwn solo cuando requiera formato; en botones/inputs usa plain_text. Mensajes concisos y escaneables (bullets, saltos de línea).
  • Listas: viñetas o pasos en section con mrkdwn; pares clave/valor cortos en section.fields (no párrafos largos en fields).
  • Interactividad: cada elemento necesita action_id estable y value pequeño (IDs, no blobs). Responde con feedback inmediato (actualiza mensaje o efímero).
  • Accesibilidad: alt_text en imágenes. Siempre incluir text top-level como fallback.
  • Límites: no más de 1–3 acciones por mensaje; divide bloques largos con divider.
  • Evita: botones sin action_id, payloads grandes en value, mrkdwn en plain_text, textos kilométricos en un solo bloque.

Ejemplo base

{
"blocks": [
{ "type": "header", "text": { "type": "plain_text", "text": "Revisión pendiente" } },
{ "type": "section",
"text": { "type": "mrkdwn", "text": "*Artículo:* Guía Block Kit\n*Autor:* @ana\n*Estado:* Listo para revisión" },
"accessory": { "type": "button", "text": { "type": "plain_text", "text": "Ver" }, "url": "https://example.com/review/123", "action_id": "open_review" }
},
{ "type": "actions",
"elements": [
{ "type": "button", "style": "primary", "text": { "type": "plain_text", "text": "Aprobar" }, "value": "approve_123", "action_id": "approve" },
{ "type": "button", "style": "danger", "text": { "type": "plain_text", "text": "Rechazar" }, "value": "reject_123", "action_id": "reject" }
]
},
{ "type": "context", "elements": [ { "type": "mrkdwn", "text": "Recibirás confirmación al decidir." } ] }
]
}