How to Turn Jira or GitHub Issues into a Daily Slack Digest

How to Turn Jira or GitHub Issues into a Daily Slack Digest

Summary

  • The gap: the native Jira Cloud for Slack app fires a notification for every issue transition rather than a scannable summary, and it silently drops issues protected by issue-level security schemes.
  • The solution: a scheduled daily digest that queries POST /rest/api/3/search/jql for issues updated in the last 24 hours with status != "Done" and posts one message at a fixed time.
  • Build path: format results as Slack Block Kit blocks (50 per message max), post via chat.postMessage, then schedule with 0 9 * * 1-5 in cron, GitHub Actions, or Jira Automation.
  • Do not fail silently: post a message even on zero results, log every run, and enable job-failure alerts.
  • Managed option: Jinba App runs the same digest as a scheduled, governed team task with a Slack connector, shared workflow connections, and an optional human approval gate before posting.

Teams running a Jira Slack integration quickly discover a gap the native tooling does not close: important issues get missed because no one is monitoring the tracker. A common pattern is that teams want to pull a filtered Jira report into Slack so members can read through items before a meeting without leaving the app. The native integration does not deliver that. It delivers a stream of per-event notifications that channels learn to ignore.

The solution is a daily digest: one message, posted at a fixed time, summarising exactly the issues a team needs to act on. This article walks through how to build it.

Why the native Jira Cloud for Slack app falls short

The Jira Cloud for Slack app is designed around per-event actions. It pushes a notification for every issue transition, offers channel-space subscriptions that fire on each update, and previews links inline. That model works for one-at-a-time triage. It does not produce a scannable summary.

There is a second problem. The native app suppresses Slack notifications for work items protected by issue-level security schemes. These issues are omitted from the feed with no indication that anything was excluded. The result is a silent miss: the team receives no signal, and the issue remains unattended.

A digest approach solves both problems. It consolidates updates into a single daily message, applies configurable filters, and makes the absence of issues explicit.

Step 1: Fetch the issues

Jira

Use the Jira Cloud REST API endpoint POST /rest/api/3/search/jql. The legacy GET /rest/api/3/search endpoint has been fully removed from Jira Cloud.

Send a JSON body rather than URL-encoding the query string. A 400 Bad Request response on a GET request usually indicates the JQL was not encoded correctly. The POST form avoids that entirely.

Request body:

{
"jql": "project = \"PROJ\" AND updated >= -1d AND status != \"Done\" ORDER BY updated DESC",
"maxResults": 100,
"fields": ["summary", "status", "assignee", "updated"]
}

Authentication is HTTP Basic using email:API_TOKEN as the credential.

For pagination, the response includes a nextPageToken. Pass it in subsequent requests to retrieve additional pages. The startAt parameter is deprecated and should not be used.

GitHub

Use GET /repos/{owner}/{repo}/issues with the headers Accept: application/vnd.github+json and X-GitHub-Api-Version: 2022-11-28. Filter with query parameters: state=open, since=YYYY-MM-DDTHH:MM:SSZ, and optionally assignee=USERNAME.

One detail matters: the GitHub issues endpoint returns both issues and pull requests. A pull request is an issue object with a pull_request key attached. Filter out any item where that key is present, or the digest will include PRs alongside issues.

The returned object provides everything the digest needs: html_url, number, title, state, assignee.login, and updated_at.

Step 2: Format the payload with Block Kit

Raw JSON posted to Slack is unreadable in a channel. Slack Block Kit structures a message as an array of typed blocks, each described as a JSON object. A single message supports up to 50 blocks.

A practical digest structure:

  • A header block with the date: Daily Jira Digest: YYYY-MM-DD
  • A divider block
  • One section block per issue, using mrkdwn for inline formatting

Example section block for a single issue:

{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*PROJ-42: New Login Bug*\n*Status:* In Progress | *Assignee:* Jane Doe"
}
}

The script loops through the API results from Step 1 and generates an array of these blocks. Because the core data shape across Jira and GitHub is the same (a title, a URL, a status, and an assignee), a single script parameterised with --source jira or --source github handles both.

Step 3: Post to Slack

Make a POST request to the Slack chat.postMessage endpoint with the channel ID and the blocks array in the request body. The request requires a Slack Bot Token with the chat:write scope in the Authorization header.

Step 4: Schedule with cron

A daily digest requires a scheduler. The standard tool is a cron expression.

0 9 * * 1-5 runs the job at 09:00 UTC on every weekday. That expression works in a Linux crontab, a GitHub Actions workflow, and Jira Automation's Scheduled trigger, which fires rules on a defined schedule.

Complete GitHub Actions example

GitHub Actions is a practical host for this job. The workflow file lives in the repository, runs are logged, and secrets are managed through the repository settings.

name: Daily Issue Digest

on:
schedule:
- cron: '0 9 * * 1-5'
workflow_dispatch:

jobs:
build-and-send-digest:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install dependencies
run: pip install requests

- name: Run digest script
env:
JIRA_URL: ${{ secrets.JIRA_URL }}
JIRA_USER: ${{ secrets.JIRA_USER }}
JIRA_TOKEN: ${{ secrets.JIRA_TOKEN }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }}
run: python create_digest.py --source jira

Key parts of the file:

  • on.schedule.cron sets the execution cadence. workflow_dispatch allows a manual trigger for testing.
  • env injects secrets without exposing them in the script source.
  • run calls the Python script that performs steps 1 through 3.

Configure GitHub Actions workflow notifications to alert on failures. A digest job that fails silently recreates the original problem.

Preventing silent failures in the digest itself

The digest is meant to surface issues that would otherwise be missed. If the digest job itself fails silently, it becomes the problem it was built to solve.

Three practices reduce that risk:

  1. Post on zero results. If the JQL or GitHub query returns no issues, the script should still post a message confirming the run completed: "No issues updated in the last 24 hours." Silence should not be indistinguishable from failure.
  2. Log every run. Record the issue count, any pagination calls, and the Slack API response status. Atlassian's own automation examples close with an audit log action for exactly this reason.
  3. Alert on job failure. For GitHub Actions, enable workflow failure notifications. For Jira Automation, the run history is visible in the automation console. Either way, a failed run should produce a visible signal.

The managed alternative: Jinba App Neo

Building and maintaining a digest script is achievable, but it carries ongoing cost: dependencies to update, secrets to rotate, and failures to monitor. Teams that want the same outcome without the maintenance surface can use Jinba App Neo, a platform for governed, shared Claude agents for a team.

Jinba App Neo covers the full digest workflow without requiring a separate scheduler or script host:

  • Scheduled task runs replace the cron job. Each run is recorded as a reviewable chat thread, which provides the audit trail that a bare cron job lacks.
  • Slack connector allows the agent to post messages on a user's behalf, handling the chat.postMessage call directly.
  • Jinba Flow connections let teams publish the fetch-format-post steps as a single callable workflow. The agent executes it in-chat with a live status card, and file outputs chain between steps automatically.
  • Human-in-the-loop approval adds an optional WAIT_FOR_APPROVAL gate. The agent can draft the digest and pause before posting, waiting for a team lead to approve or reject via an in-chat card or the run console. This is useful when the digest summarises sensitive or high-priority issues that benefit from a review before they reach the main channel.

What to do next

The per-event notification model that ships with most Jira Slack integrations is a feed, and feeds get muted. A digest posts once, at a predictable time, with exactly the issues the team needs to see.

The path to get there is the same regardless of whether the source is Jira or GitHub:

  1. Query the API with a JQL filter or GitHub issue parameters scoped to the last 24 hours.
  2. Format the results as Block Kit blocks.
  3. Post to a dedicated Slack channel via chat.postMessage.
  4. Run the job on a 0 9 * * 1-5 cron schedule and alert on failure.

Build this into a GitHub Actions workflow for a version-controlled, auditable setup. Or use Jinba App Neo if the team needs scheduling, governance, and human approval steps in a managed package.

Either way, start with Step 1: write the JQL. Everything else follows from the query.

Frequently Asked Questions About Jira Slack Digests

What is a Jira Slack daily digest?

A Jira Slack daily digest is a single scheduled Slack message that summarizes the Jira issues a team needs to act on, instead of sending a notification for every update. It typically runs once each weekday, applies a JQL filter such as issues updated in the last 24 hours that are not Done, and posts the results to a dedicated Slack channel using Slack Block Kit. The digest makes the daily review scannable and keeps routine Jira noise out of the channel.

Why does the native Jira Cloud for Slack app not send a daily digest?

The native Jira Cloud for Slack app is built for per-event notifications rather than consolidated summaries. It pushes alerts on issue transitions, supports channel-space subscriptions that fire on each update, and previews links inline. That model is useful for one-at-a-time triage, but it does not produce a single daily message that lists all relevant issues. A custom digest fills that gap by querying Jira on a schedule and posting one formatted summary.

How do I create a daily Jira digest in Slack?

To create a daily Jira digest in Slack, query Jira for the relevant issues, format them as Slack Block Kit blocks, post them with chat.postMessage, and run the job on a schedule. Use POST /rest/api/3/search/jql with a JQL filter such as updated >= -1d AND status != "Done", build one section block per issue, and schedule the script with cron or GitHub Actions. A dedicated channel and a consistent posting time make the digest easier to scan.

Which Jira API endpoint should I use for a Slack digest?

Use the Jira Cloud REST API endpoint POST /rest/api/3/search/jql for a Slack digest. The legacy GET /rest/api/3/search endpoint has been removed from Jira Cloud, and the POST form avoids URL-encoding problems with JQL. Send the JQL in a JSON request body, authenticate with HTTP Basic using email:API_TOKEN, and use the returned nextPageToken for pagination instead of the deprecated startAt parameter.

How do I format Jira issues in a Slack message?

Format Jira issues in Slack with Block Kit, Slack's structured message format built from an array of typed JSON blocks. A practical digest uses a header block for the date, a divider, and one section block per issue with mrkdwn for the summary, status, assignee, and link. Slack supports up to 50 blocks per message, so if a digest regularly exceeds that limit, split it into multiple messages or tighten the JQL filter.

How do I schedule a daily Jira Slack digest?

Schedule a daily Jira Slack digest with a cron expression, GitHub Actions schedule, or Jira Automation scheduled trigger. The cron expression 0 9 * * 1-5 runs the job at 09:00 UTC on weekdays, and it works in a Linux crontab, a GitHub Actions workflow, and Jira Automation. Set the schedule to match the team's time zone and standup cadence, and enable failure alerts so a missed run does not go unnoticed.

Why are some Jira issues missing from Slack notifications?

Some Jira issues are missing from Slack notifications because the native Jira Cloud for Slack app suppresses notifications for work items protected by issue-level security schemes. Those issues can be omitted from the feed without any indication that something was excluded. That is a silent miss. A custom digest helps by applying configurable filters and by posting an explicit zero-results message, but you should still review issue-level security permissions to confirm the automation can access the issues it needs.

How do I stop a Jira Slack digest from failing silently?

Stop a Jira Slack digest from failing silently by posting on zero results, logging every run, and alerting on job failure. If the query returns no issues, the script should still post a message such as "No issues updated in the last 24 hours" so silence is not confused with failure. Log the issue count, pagination calls, and Slack API response status, then enable workflow failure notifications in GitHub Actions or check run history in Jira Automation.

Can I combine Jira and GitHub issues in one Slack digest?

Yes. Jira and GitHub issues can be combined in one Slack digest because both sources can be normalized to the same data shape: a title, URL, status, and assignee. Use POST /rest/api/3/search/jql for Jira and GET /repos/{owner}/{repo}/issues for GitHub, then filter out GitHub items that contain a pull_request key so pull requests are not mixed in with issues. A single script parameterized with --source jira or --source github can format and post both.

Is there a no-code way to send scheduled Jira digests to Slack?

Yes, Jinba App Neo provides a managed way to send scheduled Jira digests to Slack without maintaining a separate script or cron host. It supports scheduled task runs recorded as reviewable chat threads, a Slack connector for posting messages, Jinba Flow connections for the fetch-format-post workflow, and an optional WAIT_FOR_APPROVAL gate before the digest is posted. That makes it a fit for teams that want scheduling, governance, and human approval in one package.

人馬一体のワークフロー構築を体験せよ

エンタープライズ組織を支えるAI基盤

無料で始める