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_TOKENis set in.envor the environment; the handler loads it automatically. - Run commands from the
pla-cliroot; PHP 8.1+ is already used in the project. - The bot must belong to the target channel; the handler will attempt
conversations.joinautomatically 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
channelorts. - For large channels,
conversations.repliespaginates vianext_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.postMessagewill 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:header→section→actions→context→dividersegún necesidad. - Texto:
mrkdwnsolo cuando requiera formato; en botones/inputs usaplain_text. Mensajes concisos y escaneables (bullets, saltos de línea). - Listas: viñetas o pasos en
sectionconmrkdwn; pares clave/valor cortos ensection.fields(no párrafos largos en fields). - Interactividad: cada elemento necesita
action_idestable yvaluepequeño (IDs, no blobs). Responde con feedback inmediato (actualiza mensaje o efímero). - Accesibilidad:
alt_texten imágenes. Siempre incluirtexttop-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 envalue,mrkdwnenplain_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." } ] }
]
}