---
title: Slacki bot
description: Saadab Slacki kanalitesse sõnumeid ja rikkalikku sisu.
category: Marketing
sublabel: SEO
author: OpenClaudia
tags: 
license: MIT
source: https://github.com/OpenClaudia/openclaudia-skills
---

# Slacki bot

Saada sõnumeid ja vormindatud sisu Slacki kanalitesse, kasutades Incoming Webhooks'i või Slack Web API-t.
Koosta Block Kitiga vormindatud teadaandeid, turundusaruandeid, mõõdikute töölaudu ja
kogukonnauudiseid.

## Eeltingimused

Vajalik on, et `SLACK_WEBHOOK_URL` või `SLACK_BOT_TOKEN` oleks määratud failis `.env`, `.env.local` või
`~/.claude/.env.global`.

```bash
source ~/.claude/.env.global 2>/dev/null
source .env 2>/dev/null
source .env.local 2>/dev/null

if [ -n "$SLACK_WEBHOOK_URL" ]; then
  echo "SLACK_WEBHOOK_URL is set. Webhook mode available."
elif [ -n "$SLACK_BOT_TOKEN" ]; then
  echo "SLACK_BOT_TOKEN is set. Web API mode available."
else
  echo "Neither SLACK_WEBHOOK_URL nor SLACK_BOT_TOKEN is set."
  echo "See the Setup Guide below to configure Slack credentials."
fi
```

Kui kumbagi muutujat pole määratud, juhenda kasutajat järgima allpool olevat seadistusjuhendi jaotist.

---

## Seadistusjuhend

### Valik A: Incoming Webhook (lihtne)

Incoming Webhooks on kiireim viis sõnumite postitamiseks. Need ei vaja OAuth-õigusi (scopes) ja on
seotud ühe kanaliga.

1. Mine aadressile https://api.slack.com/apps ja klõpsa **Create New App** > **From scratch**.
2. Anna rakendusele nimi (nt „Marketing Bot“) ja vali oma tööruum.
3. Klõpsa vasakul külgribal **Incoming Webhooks** ja lülita see sisse (**On**).
4. Klõpsa allosas **Add New Webhook to Workspace**.
5. Vali kanal, kuhu postitada, ja klõpsa **Allow**.
6. Kopeeri veebihaagi URL (algab `https://hooks.slack.com/services/...`).
7. Lisa see oma keskkonda:

```bash
echo 'SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../xxxx' >> .env
```

**Piirangud:** üks veebihaak kanali kohta. Programmiliselt ei saa sõnumeid lugeda, kanaleid loetleda ega
lõimedele vastata (pead teadma `thread_ts` väärtust varasemast API vastusest).

### Valik B: botiluba (täisfunktsionaalne)

Botiload annavad ligipääsu kogu Slack Web API-le: postita igasse kanalisse, kus bot on, vasta
lõimedele, loetle kanaleid, laadi üles faile ja palju muud.

1. Mine aadressile https://api.slack.com/apps ja klõpsa **Create New App** > **From scratch**.
2. Anna rakendusele nimi ja vali oma tööruum.
3. Klõpsa vasakul külgribal **OAuth & Permissions**.
4. Lisa jaotises **Bot Token Scopes** järgmised õigused:
   - `chat:write` - sõnumite postitamine
   - `chat:write.public` - kanalitesse postitamine ilma liitumata
   - `channels:read` - avalike kanalite loetlemine
   - `files:write` - failide üleslaadimine (valikuline, piltide/aruannete jaoks)
   - `reactions:write` - emoji-reaktsioonide lisamine (valikuline)
5. Klõpsa ülal **Install to Workspace** ja anna luba.
6. Kopeeri **Bot User OAuth Token** (algab `xoxb-`).
7. Lisa see oma keskkonda:

```bash
echo 'SLACK_BOT_TOKEN=xoxb-your-token-here' >> .env
```

8. Kutsu bot kanalitesse, kuhu see peab postitama: kirjuta igas kanalis `/invite @YourBotName`.

**Valikuline:** mugavuse huvides määra vaikekanal:

```bash
echo 'SLACK_DEFAULT_CHANNEL=#marketing' >> .env
```

---

## 1. meetod: Incoming Webhooks

### Saada lihtne tekstisõnum

```bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hello from the marketing bot!"
  }'
```

### Saada sõnum kohandatud kasutajanime ja ikooniga

```bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "New blog post published!",
    "username": "Marketing Bot",
    "icon_emoji": ":mega:"
  }'
```

### Saada sõnum Block Kitiga (veebihaak)

```bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": "New Product Launch"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Product X* is now live! Check out the announcement."
        }
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "Read the full announcement on our blog."
        },
        "accessory": {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "Read More"
          },
          "url": "https://example.com/blog/launch"
        }
      }
    ]
  }'
```

---

## 2. meetod: Slack Web API (botiluba)

Web API annab täieliku kontrolli sõnumite kohaletoimetamise, lõimede, kanalite haldamise ja muu üle.

### API baas

Kõik päringud lähevad aadressile `https://slack.com/api/` päisega `Authorization: Bearer {SLACK_BOT_TOKEN}`.

### Postita sõnum kanalisse

```bash
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "#marketing",
    "text": "Weekly metrics report is ready!",
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": "Weekly Marketing Metrics"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "Here are the numbers for this week."
        }
      }
    ]
  }'
```

Vastus sisaldab välja `ts` (ajatempel), mis identifitseerib sõnumi. Salvesta see väärtus
lõimes vastamiseks:

```bash
# Post and capture the message timestamp for threading
RESPONSE=$(curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "#marketing",
    "text": "Thread parent message"
  }')

MESSAGE_TS=$(echo "$RESPONSE" | python3 -c "import json,sys; print(json.load(sys.stdin).get('ts',''))")
echo "Message timestamp: $MESSAGE_TS"
```

### Vasta lõimes

Kasuta parameetrit `thread_ts`, et vastata olemasoleva lõime sees:

```bash
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"#marketing\",
    \"thread_ts\": \"${MESSAGE_TS}\",
    \"text\": \"This is a threaded reply with additional details.\"
  }"
```

Kui soovid vastuse ka kanalisse levitada (nii et see ilmuks ka põhivestluses),
lisa `"reply_broadcast": true`.

### Uuenda olemasolevat sõnumit

```bash
curl -s -X POST "https://slack.com/api/chat.update" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"#marketing\",
    \"ts\": \"${MESSAGE_TS}\",
    \"text\": \"Updated message content.\",
    \"blocks\": []
  }"
```

### Kustuta sõnum

```bash
curl -s -X POST "https://slack.com/api/chat.delete" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"#marketing\",
    \"ts\": \"${MESSAGE_TS}\"
  }"
```

### Loetle avalikud kanalid

Kasulik selleks, et leida, millisesse kanalisse postitada:

```bash
curl -s "https://slack.com/api/conversations.list?types=public_channel&limit=100" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" | \
  python3 -c "
import json, sys
data = json.load(sys.stdin)
for ch in data.get('channels', []):
    members = ch.get('num_members', 0)
    print(f\"#{ch['name']}  |  Members: {members}  |  ID: {ch['id']}\")
"
```

### Laadi fail kanalisse üles

```bash
curl -s -X POST "https://slack.com/api/files.uploadV2" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -F "file=@report.pdf" \
  -F "filename=weekly-report.pdf" \
  -F "channel_id=C0123456789" \
  -F "initial_comment=Here is this week's marketing report."
```

### Lisa emoji-reaktsioon

```bash
curl -s -X POST "https://slack.com/api/reactions.add" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"C0123456789\",
    \"timestamp\": \"${MESSAGE_TS}\",
    \"name\": \"white_check_mark\"
  }"
```

---

## Slack Block Kiti teatmik

Block Kit on Slacki kasutajaliidese raamistik vormindatud ja interaktiivsete sõnumite loomiseks. Sõnumid koosnevad
plokkide massiivist, millest igaühel on kindel tüüp ja struktuur.

### Plokitüübid

| Plokitüüp | Eesmärk | Toetab mrkdwn-i |
|------------|---------|-----------------|
| `header` | Suur paksus kirjas pealkiri | Ei (ainult plain_text) |
| `section` | Peamine sisuplokk teksti ja valikulise lisaelemendiga | Jah |
| `divider` | Horisontaalne eraldusjoon | Ei kohaldu |
| `image` | Täislaiusega pilt koos alt-tekstiga | Ei kohaldu |
| `context` | Väike, tuhmim tekst ja pildid (metaandmete, ajatemplite jaoks) | Jah |
| `actions` | Interaktiivsete elementide rida (nupud, valikud, kuupäevavalijad) | Ei kohaldu |
| `rich_text` | Täpsem vormindatud tekst (loendid, tsitaadid, koodiplokid) | Ei kohaldu |

### Päiseplokk

```json
{
  "type": "header",
  "text": {
    "type": "plain_text",
    "text": "Weekly Marketing Report",
    "emoji": true
  }
}
```

### Sektsiooniplokk

Lihttekstiga sektsioon:

```json
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*Traffic is up 23%* this week compared to last week.\nOrganic search drove most of the growth."
  }
}
```

Väljadega sektsioon (kaheveeruline paigutus):

```json
{
  "type": "section",
  "fields": [
    {
      "type": "mrkdwn",
      "text": "*Visitors*\n12,450"
    },
    {
      "type": "mrkdwn",
      "text": "*Signups*\n342"
    },
    {
      "type": "mrkdwn",
      "text": "*MRR*\n$28,500"
    },
    {
      "type": "mrkdwn",
      "text": "*Churn*\n1.2%"
    }
  ]
}
```

Nupu-lisaelemendiga sektsioon:

```json
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "New blog post: *How We Grew 10x in 6 Months*"
  },
  "accessory": {
    "type": "button",
    "text": {
      "type": "plain_text",
      "text": "Read Post"
    },
    "url": "https://example.com/blog/growth-story",
    "action_id": "read_blog_post"
  }
}
```

Pildi-lisaelemendiga sektsioon:

```json
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*New Feature: Dark Mode*\nOur most requested feature is finally here."
  },
  "accessory": {
    "type": "image",
    "image_url": "https://example.com/images/dark-mode-preview.png",
    "alt_text": "Dark mode preview"
  }
}
```

### Eraldusjoone plokk

```json
{
  "type": "divider"
}
```

### Pildiplokk

```json
{
  "type": "image",
  "image_url": "https://example.com/images/chart.png",
  "alt_text": "Weekly traffic chart",
  "title": {
    "type": "plain_text",
    "text": "Traffic Overview"
  }
}
```

### Kontekstiplokk

```json
{
  "type": "context",
  "elements": [
    {
      "type": "mrkdwn",
      "text": "Posted by *Marketing Team* | Feb 10, 2026"
    },
    {
      "type": "image",
      "image_url": "https://example.com/logo-small.png",
      "alt_text": "Company logo"
    }
  ]
}
```

### Tegevuste plokk (nupud)

```json
{
  "type": "actions",
  "elements": [
    {
      "type": "button",
      "text": {
        "type": "plain_text",
        "text": "Approve"
      },
      "style": "primary",
      "action_id": "approve_action",
      "value": "approved"
    },
    {
      "type": "button",
      "text": {
        "type": "plain_text",
        "text": "Reject"
      },
      "style": "danger",
      "action_id": "reject_action",
      "value": "rejected"
    },
    {
      "type": "button",
      "text": {
        "type": "plain_text",
        "text": "View Details"
      },
      "url": "https://example.com/details",
      "action_id": "view_details"
    }
  ]
}
```

Nupustiilid: `"primary"` (roheline), `"danger"` (punane) või jäta vaikimisi (hall) jaoks ära.

**Märkus interaktiivsuse kohta:** nupud, millel on `action_id` (ja puudub `url`), vajavad nupuvajutuse
andmete vastuvõtmiseks Slacki rakenduse seadetes jaotises **Interactivity & Shortcuts** seadistatud
Request URL-i. Nupud, millel on väli `url`, avavad lingi otse ega vaja taustasüsteemi.

### Block Kiti piirangud

| Piirang | Väärtus |
|-------|-------|
| Plokke sõnumi kohta | 50 |
| Märke tekstiploki kohta | 3000 |
| Märke päise kohta | 150 |
| Välju sektsiooni kohta | 10 |
| Elemente tegevuste ploki kohta | 25 |
| Elemente kontekstiploki kohta | 10 |

### Block Kit Builder

Kasuta visuaalset koostajat, et kujundada sõnumeid ja vaadata nende eelvaadet enne kodeerimist:
https://app.slack.com/block-kit-builder

---

## Slacki mrkdwn-vormindamise juhend

Slack kasutab oma markdowni varianti nimega mrkdwn. See erineb standardsest Markdownist
mitmel moel.

| Vormindus | Süntaks | Näide |
|-----------|--------|---------|
| Paks kiri | `*text*` | *paks tekst* |
| Kaldkiri | `_text_` | _kaldkirjas tekst_ |
| Läbikriipsutus | `~text~` | ~läbikriipsutatud~ |
| Kood (tekstisisene) | `` `text` `` | `inline code` |
| Koodiplokk | ` ```text``` ` | Mitmerealine koodiplokk |
| Tsitaat | `>text` | Tsiteeritud tekst |
| Link | `<https://url\|display text>` | Klõpsatav link |
| Kasutaja mainimine | `<@U0123456>` | @kasutajanimi |
| Kanali mainimine | `<#C0123456>` | #kanal |
| Emoji | `:emoji_name:` | :rocket: |
| Täpploend | Alusta rida märgiga `- ` või `* ` | Täpp-punkt |
| Nummerdatud loend | Alusta rida märgiga `1. ` | Nummerdatud punkt |
| Reavahetus | `\n` JSON-stringis | Uus rida |

**Olulised erinevused standardsest Markdownist:**
- Paks kiri kasutab ühte tärni `*bold*`, mitte kahte `**bold**`.
- Kaldkiri kasutab alakriipse `_italic_`, mitte üksikuid tärne.
- Lingid kasutavad püstkriipsuga vormingut `<url|text>`, mitte `[text](url)`.
- Pealkirju mrkdwn-is ei ole. Kasuta selle asemel plokitüüpi `header`.
- Pilte ei saa mrkdwn-i sisse paigutada. Kasuta selle asemel plokki `image` või `accessory`.

---

## Sõnumimallid

### Mall 1: tooteteadaanne

```bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":rocket: New Feature: [Feature Name]",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "We just shipped *[Feature Name]* — here is what it does and why it matters.\n\n:point_right: *What it does:* [One-sentence description]\n:point_right: *Why it matters:* [Key benefit for users]\n:point_right: *How to try it:* [Quick instructions or link]"
        }
      },
      {
        "type": "image",
        "image_url": "https://example.com/feature-screenshot.png",
        "alt_text": "Feature screenshot"
      },
      {
        "type": "divider"
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": ":newspaper: Read Announcement",
              "emoji": true
            },
            "url": "https://example.com/blog/feature-launch",
            "action_id": "read_announcement"
          },
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": ":play_or_pause_button: Watch Demo",
              "emoji": true
            },
            "url": "https://example.com/demo",
            "action_id": "watch_demo"
          }
        ]
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": "Posted by *Product Team* | :speech_balloon: Reply in thread with questions"
          }
        ]
      }
    ]
  }'
```

### Mall 2: iganädalane mõõdikute aruanne

```bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":bar_chart: Weekly Marketing Metrics — Feb 3-9, 2026",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "Here is this week'\''s performance snapshot."
        }
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":globe_with_meridians: *Website Traffic*"
        },
        "fields": [
          {
            "type": "mrkdwn",
            "text": "*Sessions*\n45,230 (:arrow_up: 12%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Unique Visitors*\n31,870 (:arrow_up: 8%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Bounce Rate*\n42.3% (:arrow_down: 2.1%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Avg. Session Duration*\n3m 42s (:arrow_up: 15s)"
          }
        ]
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":money_with_wings: *Conversion Metrics*"
        },
        "fields": [
          {
            "type": "mrkdwn",
            "text": "*Signups*\n487 (:arrow_up: 18%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Trial-to-Paid*\n12.4% (:arrow_up: 1.2%)"
          },
          {
            "type": "mrkdwn",
            "text": "*MRR*\n$52,300 (:arrow_up: $3,200)"
          },
          {
            "type": "mrkdwn",
            "text": "*Churn*\n1.8% (:arrow_down: 0.3%)"
          }
        ]
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":email: *Email Performance*"
        },
        "fields": [
          {
            "type": "mrkdwn",
            "text": "*Emails Sent*\n12,400"
          },
          {
            "type": "mrkdwn",
            "text": "*Open Rate*\n34.2%"
          },
          {
            "type": "mrkdwn",
            "text": "*Click Rate*\n4.8%"
          },
          {
            "type": "mrkdwn",
            "text": "*Unsubscribes*\n23"
          }
        ]
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:bulb: Key Takeaways*\n- Organic traffic up 15% after publishing 3 new blog posts\n- Email welcome sequence A/B test: Variant B outperformed by 22%\n- Trial signup spike on Thursday correlated with Product Hunt feature"
        }
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Full Dashboard",
              "emoji": true
            },
            "url": "https://analytics.example.com/dashboard",
            "action_id": "view_dashboard"
          }
        ]
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": "Auto-generated by Marketing Bot | Data from Google Analytics + Stripe"
          }
        ]
      }
    ]
  }'
```

### Mall 3: blogipostituse jagamine

```bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":pencil: New Blog Post Published",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*<https://example.com/blog/post-slug|Blog Post Title Here>*\n\nA brief summary of what the post covers — keep it to 2-3 sentences that capture the key value and make people want to click through."
        },
        "accessory": {
          "type": "image",
          "image_url": "https://example.com/blog/post-og-image.png",
          "alt_text": "Blog post cover image"
        }
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": ":bust_in_silhouette: Author: *Jane Smith* | :clock1: 6 min read | :label: SEO, Growth"
          }
        ]
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":mega: *Help us amplify!* Share this post on your socials. Here are ready-to-use snippets:\n\n*Twitter/X:* _Just published: [title]. [Key insight from the post]. Link in reply._\n\n*LinkedIn:* _We just published a deep dive on [topic]. Here is the #1 takeaway: [insight]._"
        }
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Read the Post",
              "emoji": true
            },
            "style": "primary",
            "url": "https://example.com/blog/post-slug",
            "action_id": "read_post"
          },
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Share on Twitter",
              "emoji": true
            },
            "url": "https://twitter.com/intent/tweet?text=Check%20out%20this%20post&url=https://example.com/blog/post-slug",
            "action_id": "share_twitter"
          },
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Share on LinkedIn",
              "emoji": true
            },
            "url": "https://www.linkedin.com/sharing/share-offsite/?url=https://example.com/blog/post-slug",
            "action_id": "share_linkedin"
          }
        ]
      }
    ]
  }'
```

### Mall 4: meeskonna uuendus / püstijalakoosolek

```bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":clipboard: Marketing Team Update — Monday, Feb 10",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:white_check_mark: Completed Last Week*\n- Launched email welcome sequence v2\n- Published 3 blog posts (SEO, product, case study)\n- Set up Google Ads remarketing campaign\n- Shipped landing page A/B test (Variant B live)"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:construction: In Progress*\n- Content calendar for March (70% done)\n- Competitor analysis report (due Wednesday)\n- Social media campaign for Product Hunt launch"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:dart: This Week'\''s Priorities*\n1. Finalize Product Hunt launch assets\n2. Send weekly newsletter (Thursday 9am)\n3. Review and approve Q1 ad spend budget\n4. Onboard new content writer"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:warning: Blockers*\n- Waiting on design team for Product Hunt gallery images\n- Need legal review on new case study before publishing"
        }
      },
      {
        "type": "divider"
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": ":speech_balloon: Reply in thread with your own updates or questions"
          }
        ]
      }
    ]
  }'
```

### Mall 5: intsident / kiireloomuline teavitus

```bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":rotating_light: Marketing Alert",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Issue:* [Brief description of the problem]\n*Impact:* [Who/what is affected]\n*Status:* :red_circle: Active\n*Owner:* <@U0123456>"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Details:*\n[Longer explanation. What happened, when it started, what we know so far.]"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Next Steps:*\n1. [Action item 1]\n2. [Action item 2]\n3. [Action item 3]"
        }
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Status Page"
            },
            "url": "https://status.example.com",
            "action_id": "status_page"
          }
        ]
      }
    ]
  }'
```

---

## Töövood

### Töövoog 1: turundusteadaande postitamine

Kui kasutaja palub postitada Slacki teadaande, tooteuuenduse või uudise:

1. **Kogu üksikasjad** - küsi teadaande pealkirja, sisu, linki, pildi URL-i ja sihtkanalit.
2. **Vali mall** - vali ülaltoodud mallide seast või koosta kohandatud Block Kiti sisu.
3. **Koosta sisu** - pane JSON kokku korrektse mrkdwn-vormindusega.
4. **Eelvaade** - näita kasutajale kogu JSON-sisu ja kirjelda, kuidas see välja näeb.
5. **Kinnitus** - palu kasutajal enne saatmist see heaks kiita.
6. **Saada** - käivita curl-käsk.
7. **Raporteeri** - näita API vastust. Web API puhul salvesta `ts` lõimede jaoks.

### Töövoog 2: iganädalaste mõõdikute postitamine

Kui kasutaja palub saata Slacki mõõdikute aruande või töölaua:

1. **Kogu mõõdikud** - küsi numbreid või aita need analüütikatööriistadest välja võtta.
2. **Vorminda väljadega** - kasuta kaheveerulise mõõdikupaigutuse jaoks `fields`-iga sektsiooniplokke.
3. **Lisa kontekst** - lisa nädalate võrdlused nooleemojidega.
4. **Lisa järeldused** - võta sektsiooniplokis kokku 2–3 peamist tähelepanekut.
5. **Lisa töölaua link** - lisa nupp, mis viib täieliku analüütika töölauani.
6. **Saada ja lõimi** - postita põhiaruanne ning seejärel üksikasjalikud jaotused vastustena lõimes.

### Töövoog 3: blogipostituse jagamine

Kui uus blogipostitus tuleb meeskonnale levitada:

1. **Hangi URL** - küsi blogipostituse URL-i või too blogist viimane postitus.
2. **Võta välja metaandmed** - kasuta WebFetchi, et võtta pealkiri, kirjeldus, autor ja OG-pilt.
3. **Koosta jagamissõnum** - kasuta malli 3 koos sotsiaalmeedias võimendamise tekstijuppidega.
4. **Lisa jagamisnupud** - lisa Twitteri ja LinkedIni intent-URL-id, mis on postitusega eeltäidetud.
5. **Postita kanalisse** - saada meeskonna turunduskanalisse.

### Töövoog 4: kogukonna kaasamine

Slacki kogukonnakanalite haldamiseks (avalikud kogukonnad, kliendikanalid):

1. **Tervitussõnumid** - postita uute liikmete liitumisel tervitussõnum koos reeglite ja ressurssidega.
2. **Ajastatud uuendused** - postita iganädalasi kokkuvõtteid populaarsetest aruteludest või uutest ressurssidest.
3. **Sündmuste teadaanded** - jaga eelseisvaid veebiseminare, AMA-sid või kohtumisi koos registreerumisnuppudega.
4. **Küsitlused ja tagasiside** - kasuta nuppudega tegevuste plokke kiire tagasiside kogumiseks.
5. **Lõimede haldamine** - vasta olemasolevates lõimedes uuenduste või vastustega.

---

## Sõnumite saatmine dünaamilise sisuga

### Koosta sisu shelli muutujatega

```bash
TITLE="Product X v2.0 Released"
DESCRIPTION="Version 2.0 includes dark mode, API improvements, and 3x faster performance."
LINK="https://example.com/changelog/v2"
IMAGE_URL="https://example.com/images/v2-banner.png"
CHANNEL="#announcements"

curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "$(python3 -c "
import json
payload = {
    'channel': '${CHANNEL}',
    'text': '${TITLE}',
    'blocks': [
        {
            'type': 'header',
            'text': {'type': 'plain_text', 'text': '${TITLE}', 'emoji': True}
        },
        {
            'type': 'section',
            'text': {'type': 'mrkdwn', 'text': '${DESCRIPTION}'}
        },
        {
            'type': 'image',
            'image_url': '${IMAGE_URL}',
            'alt_text': '${TITLE}'
        },
        {
            'type': 'actions',
            'elements': [{
                'type': 'button',
                'text': {'type': 'plain_text', 'text': 'Learn More'},
                'url': '${LINK}',
                'style': 'primary',
                'action_id': 'learn_more'
            }]
        }
    ]
}
print(json.dumps(payload))
")"
```

### Koosta sisu JSON-failist

Keerukate sõnumite puhul kirjuta sisu esmalt faili:

```bash
# Write the payload
cat > /tmp/slack-message.json << 'PAYLOAD'
{
  "channel": "#marketing",
  "text": "Fallback text for notifications",
  "blocks": [
    {
      "type": "header",
      "text": {
        "type": "plain_text",
        "text": "Message Title"
      }
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "Message body with *bold* and _italic_ formatting."
      }
    }
  ]
}
PAYLOAD

# Send it
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d @/tmp/slack-message.json
```

---

## Ajastatud sõnumid

Postita sõnum kindlal tulevasel ajal, kasutades `chat.scheduleMessage`:

```bash
# Schedule a message for a specific Unix timestamp
# Use: date -d "2026-02-12 09:00:00" +%s (Linux) or date -j -f "%Y-%m-%d %H:%M:%S" "2026-02-12 09:00:00" +%s (macOS)
SEND_AT=$(date -j -f "%Y-%m-%d %H:%M:%S" "2026-02-12 09:00:00" +%s 2>/dev/null || date -d "2026-02-12 09:00:00" +%s)

curl -s -X POST "https://slack.com/api/chat.scheduleMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"#marketing\",
    \"post_at\": ${SEND_AT},
    \"text\": \"Good morning team! Here is today's marketing agenda.\",
    \"blocks\": []
  }"
```

Loetle ajastatud sõnumid:

```bash
curl -s "https://slack.com/api/chat.scheduledMessages.list" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" | \
  python3 -c "
import json, sys, datetime
data = json.load(sys.stdin)
for msg in data.get('scheduled_messages', []):
    ts = datetime.datetime.fromtimestamp(msg['post_at']).strftime('%Y-%m-%d %H:%M')
    print(f\"ID: {msg['id']}  |  Channel: {msg['channel_id']}  |  Scheduled: {ts}\")
"
```

Kustuta ajastatud sõnum:

```bash
curl -s -X POST "https://slack.com/api/chat.deleteScheduledMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "C0123456789",
    "scheduled_message_id": "Q0123456789"
  }'
```

---

## Mitmesse kanalisse postitamine

Postita sama sõnum mitmesse kanalisse:

```bash
CHANNELS=("#marketing" "#general" "#product")
MESSAGE='{"text":"Big announcement coming tomorrow!","blocks":[{"type":"section","text":{"type":"mrkdwn","text":":mega: *Big announcement coming tomorrow!* Stay tuned."}}]}'

for CHANNEL in "${CHANNELS[@]}"; do
  echo "Posting to ${CHANNEL}..."
  echo "$MESSAGE" | python3 -c "
import json, sys
msg = json.load(sys.stdin)
msg['channel'] = '${CHANNEL}'
print(json.dumps(msg))
" | curl -s -X POST "https://slack.com/api/chat.postMessage" \
    -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
    -H "Content-Type: application/json" \
    -d @- | python3 -c "
import json, sys
r = json.load(sys.stdin)
if r.get('ok'):
    print(f'  Sent. ts={r[\"ts\"]}')
else:
    print(f'  Error: {r.get(\"error\", \"unknown\")}')
"
done
```

---

## Vigade käsitlemine

### Levinud API vead

| Viga | Põhjus | Lahendus |
|-------|-------|-----|
| `invalid_auth` | Vigane või aegunud luba | Loo botiluba Slacki rakenduse seadetes uuesti |
| `channel_not_found` | Bot pole kanalis või kanali nimi on vale | Kutsu bot käsuga `/invite @BotName` või kasuta kanali ID-d |
| `not_in_channel` | Bot peab esmalt kanaliga liituma | Kutsu bot kanalisse või kasuta õigust `chat:write.public` |
| `too_many_attachments` | Üle 50 ploki | Jaga sõnum mitmeks postituseks või lõimevastuseks |
| `msg_too_long` | Tekst ületab 40 000 märki | Lühenda sõnumit või jaga see osadeks |
| `rate_limited` | Liiga palju päringuid | Oota päises `Retry-After` toodud arv sekundeid |
| `missing_scope` | Loal puudub vajalik õigus | Lisa õigus jaotises OAuth & Permissions ja paigalda rakendus uuesti |

### Kontrolli vastust

```bash
RESPONSE=$(curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"channel":"#marketing","text":"Test message"}')

python3 -c "
import json, sys
r = json.loads('${RESPONSE}'.replace(\"'\", \"\"))
if r.get('ok'):
    print(f'Message sent successfully. ts={r[\"ts\"]} channel={r[\"channel\"]}')
else:
    print(f'Error: {r.get(\"error\", \"unknown\")}')
    if r.get('response_metadata', {}).get('messages'):
        for m in r['response_metadata']['messages']:
            print(f'  Detail: {m}')
" 2>/dev/null || echo "$RESPONSE"
```

Töökindlam lähenemine ajutise failiga:

```bash
RESPONSE_FILE=$(mktemp)
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"channel":"#marketing","text":"Test message"}' \
  -o "$RESPONSE_FILE"

python3 -c "
import json
with open('${RESPONSE_FILE}') as f:
    r = json.load(f)
if r.get('ok'):
    print(f'Sent. ts={r[\"ts\"]}')
else:
    print(f'Error: {r.get(\"error\")}')
"
rm -f "$RESPONSE_FILE"
```

---

## Nõuanded

- Lisa alati `blocks` kõrvale väli `text` — see on varuvariant teavituste, ekraanilugejate
  ja klientide jaoks, mis Block Kiti ei toeta.
- Kasuta Block Kit Builderit aadressil https://app.slack.com/block-kit-builder, et sõnumeid visuaalselt
  kujundada ja nende eelvaadet näha enne curl-käskude koostamist.
- Tootmistöövoogudes eelista veebihaakidele `chat.postMessage`-i (Web API). See tagastab
  sõnumi `ts`, mida saad kasutada lõimimiseks, uuendamiseks ja kustutamiseks.
- Pane pikad aruanded lõime. Postita kokkuvõte vanemsõnumina ja üksikasjad lõimevastustena,
  et kanalid püsiksid korras.
- Kasuta `plain_text` väljades `:emoji:` koode koos `"emoji": true`-ga, et kuvada emojisid päistes
  ja nuppude siltides.
- Varjesta mrkdwn-is erimärgid: `&` muutub `&amp;`, `<` muutub `&lt;`, `>` muutub `&gt;`.
- Kiiruspiirangud: Slack lubab umbes 1 sõnumi sekundis kanali kohta. Massiliseks postitamiseks lisa
  päringute vahele 1-sekundiline viivitus.
- Mõõdikute postitamisel kasuta kaheveerulise paigutuse jaoks sektsiooni `fields`, selle asemel et
  proovida mrkdwn-is tabeleid vormindada (Slack ei toeta tabeleid).
- **Näita kasutajale alati kogu sõnumi sisu ja küsi enne postitamist kinnitust.**