DEV Community

Nexus Labs
Nexus Labs

Posted on

Taming Friday Updates: My Journey Automating Jira & Confluence with a Custom GPT

Friday afternoons. For years, they’ve been synonymous with one thing for me: the weekly project update compilation. You know the drill: trawl through Jira tickets, peek at Confluence pages, copy-paste snippets, and then try to condense a week’s worth of chaos into a few palatable bullet points for stakeholders. It's soul-crushing, eats up an hour or two I'd rather spend wrapping up actual work, and frankly, I dread it.

I finally snapped. With all the buzz around custom GPTs, I thought, "Surely this is what they're for." I wasn't looking for AGI to solve world hunger, just something to give me my Friday back. Here’s how I actually did it, including the part that made me want to throw my monitor.

1. Identify the Data Sources and the Pain

The pain was obvious: manual aggregation. The sources were Jira (for ticket statuses, sprints, epics) and Confluence (for meeting notes, design docs, broader project context). My goal wasn't just to collect the data, but to synthesize it. Stakeholders don't want a data dump; they want a clear, concise summary of what happened, what's next, and any blockers. This required intelligence, not just scripting.

2. Getting the Data Out (The Hard Part)

This step was the biggest hurdle. My initial naive thought was to manually copy and paste into a text file and feed that to the GPT. But that defeats the entire purpose of automation. I needed programmatic access.

  • Jira Cloud: Relatively straightforward. I used a Python script leveraging requests to hit the Jira Cloud REST API. Authenticating with an API token was simple enough. I fetched issues related to our active sprint, filtering by project and status. The JSON responses are well-structured.
  • Confluence Cloud: Oh, Confluence. This is where things went sideways. My script was pulling page content via the Confluence Cloud REST API /wiki/rest/api/content/{id} endpoint. The body.storage format is a beast. It's not clean Markdown or even HTML; it’s Atlassian Document Format (ADF), a JSON-based format that's basically a highly structured rich text representation.

    What didn't go as planned: I spent an entire Saturday wrestling with ADF. It's nested, full of obscure types, and just plain ugly to parse into something a text-based LLM could easily digest. My first attempts at just passing the raw ADF JSON to the GPT resulted in confusing, verbose summaries. The GPT tried to "understand" the JSON structure instead of just the content. I needed plain text.

    After several hours of head-desking, I built a crude recursive parser in Python. It iterated through the ADF tree, extracting text nodes, links, and list items, ignoring formatting unless it was critical (like headings). It wasn't perfect, but it transformed this:

    {
    "type": "doc",
    "version": 1,
    "content": [
    {
    "type": "paragraph",
    "content": [
    { "type": "text", "text": "Weekly Sync Notes:" }
    ]
    },
    {
    "type": "bulletList",
    "content": [
    {
    "type": "listItem",
    "content": [
    {
    "type": "paragraph",
    "content": [
    { "type": "text", "text": "Resolved " },
    {
    "type": "inlineCard",
    "attrs": {
    "url": "https://yourinstance.atlassian.net/browse/PROJ-123"
    }
    },
    { "type": "text", "text": " - UI Bug" }
    ]
    }
    ]
    }
    ]
    }
    ]
    }

    Into something like:
    Weekly Sync Notes:\n* Resolved PROJ-123 - UI Bug

    It took me roughly 5 hours just for this ADF parsing step, way more than I anticipated.

3. Crafting the Custom GPT Persona and Instructions

Once I had the raw data (Jira summaries, Confluence notes parsed into readable text), it was time for the GPT. I designed a custom GPT called "Friday Report Bot." Its instructions were key:

  • Persona: "You are a concise project manager reporting to executive stakeholders. Be direct, factual, and highlight key achievements, upcoming work, risks, and blockers. Do not elaborate unless necessary."
  • Output Format: "Generate a summary with these sections: 'Key Achievements', 'Next Week's Focus', 'Risks & Blockers'."
  • Input Handling: "I will provide you with a dump of Jira ticket summaries and relevant Confluence notes. Synthesize this information. If you see 'PROJ-XYZ' mentioned, look for its summary in the Jira data."

I trained it with a few examples of good and bad summaries I'd made in the past.

4. Orchestration and The First Run

My Python script now:

  1. Fetches Jira issues.
  2. Fetches Confluence pages (the main weekly update page, plus any linked relevant docs).
  3. Parses the Confluence ADF into plain text.
  4. Combines all this into a single, structured string. Something like:

    Jira Tickets:

    • PROJ-101: Implement Feature X (DONE)
    • PROJ-102: Fix Bug Y (IN PROGRESS) ## Confluence Notes:
    • Weekly Sync (Oct 2): Feature X deployed. Discovered critical perf issue.
    • Design Doc for Feature Z (draft): Approval pending.

Then, I pasted this entire blob into my custom GPT and hit enter. The first summary it spat out was... decent. It wasn't perfect, but it had the structure I wanted, and it pulled out the key items. It reduced my active "reporting" time from easily 90-120 minutes of mental agony to about 10 minutes of review and minor edits.

The Payoff: My Fridays are (mostly) Mine Again

The whole setup took me about 8 hours over two weekends, mostly due to that Confluence ADF parser. Was it worth it? Absolutely. I’ve gone from dreading Friday afternoons to almost looking forward to seeing what the bot comes up with. It's not perfect, I still do a quick review and sometimes tweak a sentence or two, but the heavy lifting of sifting and summarizing is gone. It's a small win, but it feels huge.

If you’re drowning in manual reporting, look at custom GPTs or even just clever scripting. The initial investment of time can really pay off. And seriously, avoid ADF if you can. Or just prepare for a headache.

Top comments (0)