Sitemap

Python ile Jira Zaman Takibi Otomasyonu: Günlük API ve Cron Tabanlı Çözüm

8 min readApr 25, 2025

--

Hazırlayan: Burak Ceviz — DevSecOps Engineer — Sekom

Jira üzerinde günlük zaman takibini manuel olarak yapmak hem zaman kaybına neden olur hem de hata riskini artırır. Bu yazıda, Python ile geliştirilen bir otomasyon script’i aracılığıyla Jira’daki işlerinize otomatik olarak zaman kaydı nasıl yapılır, adım adım öğreneceksiniz.

Script, Jira REST API, cron zamanlayıcı, resmî tatil kontrolü, e-posta ve Microsoft Teams bildirimleri gibi özelliklerle donatılmıştır. Böylece hafta içi her gün, tanımladığınız Jira görevlerine çalışma süresi otomatik olarak işlenir. Üstelik bu çözüm, teknik bilgi seviyesi ne olursa olsun her ekip üyesi tarafından kolaylıkla uygulanabilir.

Otomasyon şu özellikleri içerecek:

● Hafta içi günlerinde otomatik zaman girişi

● Resmî tatillere duyarlı çalışma

● Günlük e-posta bilgilendirmeleri

● Cron kullanılarak zamanlanmış çalıştırma

Microsoft Teams bildirimleri (e-posta alternatifi olarak) sayesinde, Jira REST API kullanılarak belirli Jira işlerine günlük çalışma süresi otomatik olarak kaydedilir. Otomasyon şu işlevleri içerir:

● Hafta içi günlerinde otomatik zaman kaydı

● Resmî tatil günlerine duyarlılık

● Günlük e-posta bildirimleri

● Cron ile zamanlanmış çalıştırma

Bu eğitimin sonunda, Jira ile sorunsuz şekilde entegre olan sağlam bir günlük takip çözümüne sahip olacaksınız.

✨ Kullanılan Teknolojiler

● Python 3

● Jira REST API

● Crontab (Linux)

● SMTP (e-posta uyarıları için)

● Microsoft Teams Giriş Webhook’u (opsiyonel e-posta alternatifi)

🔑 Ön Koşul: Jira API Token Oluşturma

Jira REST API’yi kullanabilmek için Atlassian hesabınızdan bir API token oluşturmanız gerekir.

Token oluşturma adımları:

  1. https://id.atlassian.com/manage/api-tokens adresine gidin
  2. “Create API token” butonuna tıklayın
  3. “jira-worklog-script” gibi bir etiket verin
  4. “Create” ve ardından “Copy” butonlarına tıklayın
  5. Token’ı güvenli bir yerde saklayın — bu token’ı şifre yerine kullanacaksınız

Bu token, Jira API istekleri sırasında Basic Auth yönteminde şifre olarak kullanılacak. Kullanıcı adınız ise e-posta adresiniz olacak.

Olası Güvenlik Riskleri ve API Token Yönetimi

Script’te API_TOKEN, EMAIL gibi hassas bilgiler düz metin olarak yazıldığında güvenlik riski doğar. Bu nedenle çevresel değişken (.env) kullanımı tavsiye edilir.

🔐 dotenv Kullanımı:

1).env dosyası oluştur:
ini
JIRA_EMAIL=you@example.com
JIRA_API_TOKEN=abc123xyz456
2) python-dotenv ile içeri aktar:
from dotenv import load_dotenv
import os
load_dotenv()
EMAIL = os.getenv("JIRA_EMAIL")
API_TOKEN = os.getenv("JIRA_API_TOKEN")

Böylece token’lar kaynak koddan ayrılır ve sürüm kontrolüne dahil edilmez.

📅 Script’in Genel Yapısı

Python dosyasında tanımlanan Jira görev listesi şu alanları içerir:

● key: Jira iş anahtarı (örneğin: Project-46)

● hour: Başlangıç saati

● duration: Harcanan süre (örn: “30m”)

● comment: Jira iş kaydına eklenecek açıklama

ISSUES = [
{"key": "Project-46", "hour": time(9, 30), "duration": "30m", "comment": "Daily stand-up meeting."}, {"key": "DEVSECOPS-4646", "hour": time(10, 0), "duration": "40m", "comment": "Documentation and planning."}, {"key": "Operation-160", "hour": time(11, 0), "duration": "20m", "comment": "Email reviews and responses."}]

Script, /rest/api/3/issue/{issueIdOrKey}/worklog endpoint’ini kullanarak bu girişleri Jira’ya işler. Hafta sonu veya resmi tatillerde giriş yapılmaz. Başarılı girişlerin özeti günlük e-posta ile gönderilir.

Yılın son günü (31 Aralık) için özel bir uyarı da eklidir:
📌 Yeni yıl için tatil listesi güncellenmeli!

Jira İş Anahtarları Otomatik Olarak Nasıl Alınır?

Statik ISSUES = […] listesi yerine, Jira’dan aktif işleri çekmek mümkündür. Örneğin belirli bir kullanıcıya atanan işleri çekmek için aşağıdaki gibi bir JQL kullanılabilir:

🧠 Örnek Python Fonksiyonu:

def get_user_issues(email, token):
jql = 'assignee = currentUser() AND statusCategory != Done ORDER BY updated DESC'
url = f"{JIRA_URL}/rest/api/3/search?jql={jql}"
headers = {"Content-Type": "application/json"}
response = requests.get(url, headers=headers, auth=(email, token))
issues = response.json().get("issues", [])
return [{"key": i["key"], "summary": i["fields"]["summary"]} for i in issues]

Bu yöntemle ISSUES listesini otomatik doldurabilir, zaman kaydı dinamikleştirilebilir.

🔧 Tam Python Script’i

Belgedeki tam script dilersen Türkçe açıklamalarla birlikte de hazırlanabilir. Kod içerisinde SMTP ayarları, Teams entegrasyonu, tarih kontrolü ve hata yönetimi dahil birçok ayrıntı yer alıyor.

import requests
import smtplib
from email.mime.text import MIMEText
from datetime import datetime, time, timedelta, timezone
JIRA_URL = "https://yourcompany.atlassian.net"
EMAIL = "your.email@company.com"
API_TOKEN = "your_api_token_here"
ISSUES = [
{"key": "Project-46", "hour": time(9, 30), "duration": "30m", "comment": "Daily stand-up meeting."},
{"key": "DEVSECOPS-4646", "hour": time(10, 0), "duration": "40m", "comment": "Documentation and planning."},
{"key": "Operation-160", "hour": time(11, 0), "duration": "20m", "comment": "Email reviews and responses."}
]
SMTP_SERVER = "smtp.gmail.com"
SMTP_PORT = 587
MAIL_USERNAME = "your.email@company.com"
MAIL_PASSWORD = "your_app_password"
MAIL_TO = "your.email@company.com"
MAIL_FROM = "your.email@company.com"
HOLIDAYS = [
"2025-04-01", "2025-04-23", "2025-05-01", "2025-05-19",
"2025-06-05", "2025-06-06", "2025-06-09", "2025-07-15",
"2025-10-28", "2025-10-29", "2025-12-31"
]
turkey_tz = timezone(timedelta(hours=3))
today = datetime.now(turkey_tz)
today_str = today.strftime("%Y-%m-%d")
if today.weekday() >= 5 or today_str in HOLIDAYS:
print("Today is a holiday or weekend. Exiting.")
exit()
def send_email(subject, body):
msg = MIMEText(body)
msg["Subject"] = subject
msg["From"] = MAIL_FROM
msg["To"] = MAIL_TO
server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
server.starttls()
server.login(MAIL_USERNAME, MAIL_PASSWORD)
server.sendmail(MAIL_FROM, MAIL_TO, msg.as_string())
server.quit()
def get_issue_summary(issue_key):
issue_url = f"{JIRA_URL}/rest/api/3/issue/{issue_key}"
response = requests.get(issue_url, auth=(EMAIL, API_TOKEN))
if response.status_code == 200:
return response.json()["fields"]["summary"]
return "Summary could not be retrieved"
new_year_warning = "\n📌 Remember to update the official holiday list for the new year!\n" if today_str == "2025-12-31" else ""log_messages = []
for item in ISSUES:
started_datetime = datetime.combine(today.date(), item["hour"]).replace(tzinfo=turkey_tz)
started_str = started_datetime.strftime("%Y-%m-%dT%H:%M:%S.000%z")
payload = {
"started": started_str,
"timeSpent": item["duration"],
"comment": {
"type": "doc",
"version": 1,
"content": [{
"type": "paragraph",
"content": [{"text": item["comment"], "type": "text"}]
}]
}
}
headers = {"Content-Type": "application/json"}
response = requests.post(
f"{JIRA_URL}/rest/api/3/issue/{item['key']}/worklog",
json=payload, headers=headers, auth=(EMAIL, API_TOKEN)
)
summary = get_issue_summary(item["key"])
if response.status_code == 201:
log_messages.append(f"Issue: {item['key']} - {summary}\nDuration: {item['duration']}\n")
else:
send_email(f"❌ Jira Worklog ERROR - {item['key']}",
f"Issue: {item['key']}\nStatus Code: {response.status_code}\nResponse: {response.text}")
if log_messages:
mail_body = f"""{today_str} Jira worklog entries completed. If today is a personal leave, please remove them manually in Jira.\n\n"""
mail_body += "\n".join(log_messages) + new_year_warning
send_email("✅ Jira Worklog Completed", mail_body)

Jira Worklog API Nasıl Çalışır?

Jira’nın worklog endpoint’i, belirli bir iş (issue) için zaman kaydı yapılmasına olanak tanır. Bu işlem, projelerde yapılan işi belgelemek, raporlamak ve faturalamak açısından kritik öneme sahiptir. Python script’inde kullanılan POST /rest/api/3/issue/{issueIdOrKey}/worklog endpoint’i sayesinde, belirli bir iş için manuel giriş yapmadan zaman kaydı otomatik olarak işlenebilir.

🔧 API Kullanım Mantığı

Aşağıdaki örnek, bir iş kaydına 30 dakikalık bir zaman girdisini gösterir:

POST /rest/api/3/issue/DEV-123/worklog

Authorization: Basic <email:api_token>

Content-Type: application/json

JSON Payload Örneği:

{
"started": "2025-04-22T09:30:00.000+0300",
"timeSpent": "30m",
"comment": {
"type": "doc",
"version": 1,
"content": [{
"type": "paragraph",
"content": [{
"type": "text",
"text": "Daily stand-up meeting."
}]
}]
}
}

🧠 Bilmeniz Gerekenler

● started: ISO 8601 formatında zaman. Saat dilimi (+0300) dahil edilmelidir.

● timeSpent: Dakika (m), saat (h) veya gün (d) cinsinden süre.

● comment: Jira’nın yeni nesil zengin metin formatına (ADF — Atlassian Document Format) göre tanımlanır.

✅ Başarılı Yanıt

Başarılı bir işlem sonucunda Jira 201 Created status kodu döner. Yanıt, girilen iş kaydının id’sini içerir.

Resmî Tatil Günleri Python ile Nasıl Kontrol Edilir?

Script’in içerisinde sabit HOLIDAYS = […] listesi bulunur. Ancak tatiller yıllık olarak değiştiği için bu yaklaşım uzun vadede sürdürülebilir değildir. Bunun yerine bir tatil API’sinden dinamik veri çekilebilir.

🔄 Örnek : Nager.Date API ile Tatil Kontrolü

import requests
def is_today_holiday(country_code="TR"):
today_str = datetime.now().strftime("%Y-%m-%d")
year = datetime.now().year
response = requests.get(f"https://date.nager.at/api/v3/PublicHolidays/{year}/{country_code}")
if response.status_code == 200:
holidays = response.json()
return any(h["date"] == today_str for h in holidays)
return False

Bu fonksiyon sayesinde, tatiller sabit değil — dinamik olarak kontrol edilir.

🚜 Script’in Zamanlanması

Otomatik çalıştırma için crontab kullanıyoruz:

crontab -e

Script’in her gün saat 09:30'da çalışması için aşağıdaki satırı ekleyin:

30 9 * * * /usr/bin/python3 /path/to/your/worklog.py >> /path/to/your/worklog.log 2>&1

Bu yapılandırma sayesinde, script her gün çalışır; ancak yalnızca gün hafta içiyse ve resmi tatil değilse zaman kaydı yapılır.

Mail

Windows Kullanıcıları İçin Alternatif Zamanlayıcı (Task Scheduler)

Linux’ta crontab kullanmak mümkünken, Windows kullanıcıları için en yaygın çözüm Görev Zamanlayıcı (Task Scheduler) aracılığıyla script’i belirli saatlerde çalıştırmaktır.

🔧 Adımlar:

  1. Windows’ta “Görev Zamanlayıcı”yı açın
  2. “Temel Görev Oluştur” seçeneğini seçin
  3. Script’i tetikleyecek bir saat belirleyin

Eylem olarak:

Program: python
Argument: C:\Users\SeninAdin\Desktop\worklog.py

Script’in düzgün çalışabilmesi için Python’ın sistem PATH’ine ekli olması gerekir.

💳 Sağladığı Faydalar

● Zaman girişlerini manuel yapma derdi sona erer

● Ekipler arası tutarlılık sağlanır

● Tatil ve hafta sonları göz önüne alındığı için hatalar engellenir

● Günlük e-posta raporları ile bilgilendirme yapılır

📱 Opsiyonel: Microsoft Teams Entegrasyonu (E-posta Alternatifi)

Zaman girişi bildirimlerini e-posta yerine veya yanı sıra Microsoft Teams üzerinden almak isterseniz, “Incoming Webhooks” özelliğini kullanabilirsiniz.

MS notification

Adım 1: Teams’te Webhook Oluştur

  1. Teams’te ilgili kanalın yanındaki … → “Bağlayıcılar” → “Incoming Webhook”
  2. Bir isim verin, isterseniz bir ikon yükleyin
  3. Oluşan Webhook URL’sini kopyalayın

Adım 2: Script’e send_teams_message Fonksiyonunu Ekleyin

def send_teams_message(text):
TEAMS_WEBHOOK_URL = "https://your.webhook.office.com/..." # Use your real URL
headers = {"Content-Type": "application/json"}
payload = {"text": text}
try:
response = requests.post(TEAMS_WEBHOOK_URL, json=payload, headers=headers)
if response.status_code == 200:
print("📢 Teams notification sent.")
else:
print("❌ Teams notification failed:", response.text)
except Exception as e:
print("❌ Teams exception:", e)

Adım 3: E-posta Bildirimine Ekleme Yapın veya Yerine Geçin

Zaman kaydı başarılı şekilde yapıldıktan sonra, fonksiyonu aşağıdaki gibi çağırabilirsiniz:

body = f"Worklog successfully submitted on {today_str} at 09:30. If you were on leave today, please remove the worklog manually from Jira.
Issue: {ISSUE_KEY} - {issue_summary}
Duration: {TIME_SPENT}{new_year_warning}"
send_email("✅ Jira Worklog successful", body)
send_teams_message(body)

Ayrıca, isterseniz Teams mesajlarını yalnızca hata durumlarında da gönderebilirsiniz.

Python Script’in Docker ile Çalıştırılması

Script’i Docker container içinde çalıştırmak, zamanlama, dağıtım ve taşınabilirlik açısından büyük avantaj sağlar.

🐳 Örnek Dockerfile:

FROM python:3.11
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "worklog.py"]

Terminal Komutları:

docker build -t jira-worklog .
docker run --env-file .env jira-worklog

.env dosyasını — env-file ile dahil ederek güvenli çalıştırma sağlanabilir.

📊 Sonuç

Bu otomasyon, Jira, Python ve basit zamanlama mantığını entegre ederek günlük iş akışınıza verimlilik katar. Yalnızca birkaç yapılandırma ile zaman kayıtlarınızın zamanında, tutarlı ve düzenli şekilde yapılmasını sağlayabilirsiniz.

İster birden fazla Jira görevi yönetin, ister sadece zamanınızı daha etkili şekilde kaydetmek isteyin — bu çözüm ihtiyaçlarınıza göre ölçeklenebilir.

Jira Zaman Takibi Otomasyonu Hakkında Sıkça Sorulan Sorular

Bu script yalnızca Jira Cloud ile mi uyumlu?

Evet, bu script Jira Cloud REST API v3 ile uyumlu çalışır. Jira Server veya Data Center sürümleri farklı endpoint’ler kullanabileceğinden uyarlama gerektirebilir. Cloud ortamında çalışan takımlar için doğrudan entegre şekilde kullanılabilir.

API token’ımı güvenli şekilde nasıl saklamalıyım?

Token’ınızı doğrudan script içine yazmak güvenli değildir. Bunun yerine .env dosyası içinde saklayarak python-dotenv kütüphanesi ile script’e dahil etmeniz önerilir. Bu yöntemle token’ınız sürüm kontrolüne girmez.

Script farklı kullanıcılar için zaman girişi yapabilir mi?

Hayır. Jira API, yalnızca oturum açan yani token sahibi kullanıcının kendi adına zaman kaydı yapmasına izin verir. Başka kullanıcılar için işlem yapılabilmesi için her birinin ayrı token’ı ile giriş yapılmalıdır.

Script’i Windows ortamında nasıl zamanlayabilirim?

Windows kullanıcıları script’i “Görev Zamanlayıcı (Task Scheduler)” aracıyla zamanlayabilir. Python kurulu olmalı ve script tam dosya yolu ile tanımlanmalıdır. Linux’taki crontab işlevinin Windows alternatifi olarak çalışır.

Zaman kaydı yapılırken saat dilimi hatası alırsam ne yapmalıyım?

Script’te kullanılan started alanı içinde mutlaka saat dilimi bilgisi (örneğin +0300) yer almalıdır. Bu bilgi eksikse Jira varsayılan olarak UTC saatini kullanır ve girişler yanlış zamanda görünür.

--

--

Sekom
Sekom

Written by Sekom

Sekom İletişim Sistemleri, birçok farklı uzmanlık alanıyla bilişim sektöründe faaliyet gösteren, uçtan uca bir dijital dönüşüm entegratörüdür.

No responses yet