{"id":31169,"date":"2025-10-06T16:41:40","date_gmt":"2025-10-06T13:41:40","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=31169"},"modified":"2025-10-06T16:41:40","modified_gmt":"2025-10-06T13:41:40","slug":"12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/","title":{"rendered":"12 Days of DigitalOcean (Day 8) &#8211; Postmark&#8217;\u0131 Flask Uygulaman\u0131za Ba\u011flama"},"content":{"rendered":"<p><body><\/p>\n<h2>12 Days of DigitalOcean (Day 8) &#8211; Postmark&#8217;\u0131 Flask Uygulaman\u0131za Ba\u011flama<\/h2>\n<p>DigitalOcean&#8217;\u0131n &#8220;12 Days of DigitalOcean&#8221; serisi, geli\u015ftiricilere bulut platformunun sundu\u011fu \u00e7e\u015fitli hizmetleri ve pop\u00fcler teknolojilerle entegrasyonlar\u0131n\u0131 ke\u015ffetme f\u0131rsat\u0131 sunan bilgilendirici bir yolculuktur. Bu serinin sekizinci g\u00fcn\u00fcnde, odak noktam\u0131z e-posta g\u00f6nderme yeteneklerini Flask uygulamalar\u0131m\u0131za entegre etmek ve bu entegrasyon i\u00e7in Postmark gibi g\u00fc\u00e7l\u00fc bir hizmetten yararlanmakt\u0131r. Modern web uygulamalar\u0131 i\u00e7in e-posta ileti\u015fimi, kullan\u0131c\u0131 kayd\u0131ndan \u015fifre s\u0131f\u0131rlamaya, bildirimlerden pazarlama kampanyalar\u0131na kadar hayati bir bile\u015fendir. Ancak e-posta g\u00f6nderme altyap\u0131s\u0131n\u0131 s\u0131f\u0131rdan kurmak, teslim edilebilirlik, spam filtreleri ve \u00f6l\u00e7eklenebilirlik gibi karma\u015f\u0131k sorunlar\u0131 beraberinde getirir. \u0130\u015fte tam bu noktada Postmark gibi \u00f6zel e-posta servis sa\u011flay\u0131c\u0131lar\u0131 devreye girer. Bu makalede, Postmark&#8217;\u0131 bir Flask uygulamas\u0131na nas\u0131l ba\u011flayaca\u011f\u0131m\u0131z\u0131 ad\u0131m ad\u0131m inceleyecek, en iyi uygulamalar\u0131 ele alacak ve bu s\u00fcrecin neden DigitalOcean ekosisteminde sorunsuz bir deneyim sundu\u011funu a\u00e7\u0131klayaca\u011f\u0131z.<\/p>\n<h3>Neden Postmark ve Flask?<\/h3>\n<p>Uygulaman\u0131z\u0131n e-posta g\u00f6nderme ihtiya\u00e7lar\u0131 i\u00e7in Postmark&#8217;\u0131 tercih etmek, \u00f6zellikle i\u015flem e-postalar\u0131 (transactional emails) s\u00f6z konusu oldu\u011funda bir\u00e7ok avantaj sunar. Flask ile birle\u015fti\u011finde ise h\u0131zl\u0131, verimli ve \u00f6l\u00e7eklenebilir bir \u00e7\u00f6z\u00fcm elde edersiniz.<\/p>\n<h4>Postmark&#8217;\u0131n Avantajlar\u0131<\/h4>\n<p>Postmark, \u00f6zellikle i\u015flem e-postalar\u0131na odaklanm\u0131\u015f bir e-posta servis sa\u011flay\u0131c\u0131s\u0131d\u0131r. Bu odaklanma, onu di\u011fer genel e-posta hizmetlerinden ay\u0131r\u0131r ve geli\u015ftiriciler i\u00e7in cazip k\u0131lar.<\/p>\n<p>*   <strong>Y\u00fcksek Teslim Edilebilirlik (Deliverability):<\/strong> Postmark, e-postalar\u0131n\u0131z\u0131n gelen kutusuna ula\u015fmas\u0131n\u0131 sa\u011flamak i\u00e7in sekt\u00f6rdeki en iyi uygulamalar\u0131 benimser. \u00d6zel IP havuzlar\u0131, itibar y\u00f6netimi ve spam filtrelerini a\u015fma konusundaki uzmanl\u0131\u011f\u0131 sayesinde, \u00f6nemli e-postalar\u0131n\u0131z\u0131n asla kaybolmamas\u0131n\u0131 sa\u011flar.<br \/>\n*   <strong>H\u0131z:<\/strong> \u0130\u015flem e-postalar\u0131 genellikle zaman a\u00e7\u0131s\u0131ndan kritik \u00f6neme sahiptir (\u00f6rne\u011fin, \u015fifre s\u0131f\u0131rlama ba\u011flant\u0131lar\u0131 veya sipari\u015f onaylar\u0131). Postmark, e-postalar\u0131 inan\u0131lmaz bir h\u0131zla g\u00f6nderir, bu da kullan\u0131c\u0131 deneyimini \u00f6nemli \u00f6l\u00e7\u00fcde iyile\u015ftirir.<br \/>\n*   <strong>Kullan\u0131\u015fl\u0131 API:<\/strong> Postmark&#8217;\u0131n RESTful API&#8217;si son derece iyi belgelenmi\u015f ve kullan\u0131m\u0131 kolayd\u0131r. Bu, geli\u015ftiricilerin e-posta g\u00f6nderme i\u015flevselli\u011fini uygulamalar\u0131na h\u0131zl\u0131 ve sorunsuz bir \u015fekilde entegre etmelerini sa\u011flar.<br \/>\n*   <strong>\u015eablon Deste\u011fi:<\/strong> Postmark, \u00f6nceden tasarlanm\u0131\u015f veya \u00f6zel e-posta \u015fablonlar\u0131 kullanma imkan\u0131 sunar. Bu, e-postalar\u0131n\u0131z\u0131n markan\u0131zla tutarl\u0131 g\u00f6r\u00fcnmesini sa\u011flar ve dinamik i\u00e7erik eklemeyi kolayla\u015ft\u0131r\u0131r.<br \/>\n*   <strong>Detayl\u0131 Aktivite Raporlar\u0131:<\/strong> G\u00f6nderilen, teslim edilen, a\u00e7\u0131lan, t\u0131klanan ve geri d\u00f6nen e-postalar hakk\u0131nda detayl\u0131 raporlar sunar. Bu veriler, e-posta kampanyalar\u0131n\u0131z\u0131n etkinli\u011fini anlamak ve iyile\u015ftirmek i\u00e7in paha bi\u00e7ilmezdir.<br \/>\n*   <strong>Webhooks:<\/strong> E-posta olaylar\u0131n\u0131 (a\u00e7ma, t\u0131klama, teslimat vb.) uygulaman\u0131za geri bildirim olarak g\u00f6ndermek i\u00e7in webhooks \u00f6zelli\u011fini kullanabilirsiniz. Bu, e-posta ak\u0131\u015f\u0131n\u0131z\u0131 otomatikle\u015ftirmek ve kullan\u0131c\u0131 etkile\u015fimlerini takip etmek i\u00e7in g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r.<br \/>\n*   <strong>G\u00fcvenlik ve Uyum:<\/strong> Postmark, e-posta g\u00fcvenli\u011fini ve gizlili\u011fini ciddiye al\u0131r. GDPR ve di\u011fer veri koruma d\u00fczenlemelerine uyumludur.<\/p>\n<h4>Flask&#8217;\u0131n Rol\u00fc<\/h4>\n<p>Flask, Python tabanl\u0131 hafif bir mikro web \u00e7er\u00e7evesidir. B\u00fcy\u00fck ve karma\u015f\u0131k web uygulamalar\u0131 geli\u015ftirmek i\u00e7in kullan\u0131labilece\u011fi gibi, daha k\u00fc\u00e7\u00fck, amaca y\u00f6nelik hizmetler veya API&#8217;ler olu\u015fturmak i\u00e7in de idealdir.<\/p>\n<p>*   <strong>Minimalist ve Esnek:<\/strong> Flask, ihtiyac\u0131n\u0131z olan bile\u015fenleri se\u00e7me ve entegre etme konusunda size tam kontrol sa\u011flar. Bu minimalist yakla\u015f\u0131m, gereksiz y\u00fckten ka\u00e7\u0131narak h\u0131zl\u0131 ve verimli uygulamalar olu\u015fturman\u0131za olanak tan\u0131r.<br \/>\n*   <strong>\u00d6l\u00e7eklenebilirlik:<\/strong> Flask uygulamalar\u0131, do\u011fru mimari ve DigitalOcean gibi bir bulut sa\u011flay\u0131c\u0131s\u0131 ile kolayca \u00f6l\u00e7eklendirilebilir. \u0130\u015flem e-postalar\u0131 g\u00f6nderme gibi belirli bir g\u00f6revi yerine getiren bir mikro hizmet olarak da kullan\u0131labilir.<br \/>\n*   <strong>Geli\u015ftirici Dostu:<\/strong> Python&#8217;\u0131n basit ve okunabilir s\u00f6zdizimi sayesinde Flask, h\u0131zl\u0131 geli\u015ftirme ve kolay bak\u0131m sunar.<br \/>\n*   <strong>Zengin Eklenti Ekosistemi:<\/strong> Flask&#8217;\u0131n k\u00fc\u00e7\u00fck \u00e7ekirde\u011fi, bir\u00e7ok \u00fc\u00e7\u00fcnc\u00fc taraf eklenti (extension) ile geni\u015fletilebilir. Bu, veritaban\u0131 entegrasyonundan form y\u00f6netimine kadar bir\u00e7ok yayg\u0131n web geli\u015ftirme g\u00f6revini basitle\u015ftirir.<\/p>\n<p>Postmark&#8217;\u0131n sa\u011flam e-posta teslimat yetenekleri ile Flask&#8217;\u0131n \u00e7evik ve esnek yap\u0131s\u0131 bir araya geldi\u011finde, uygulaman\u0131z i\u00e7in g\u00fcvenilir ve etkili bir e-posta ileti\u015fim altyap\u0131s\u0131 olu\u015fturabilirsiniz.<\/p>\n<h3>\u00d6n Gereksinimler ve Kurulum<\/h3>\n<p>Postmark&#8217;\u0131 Flask uygulaman\u0131za entegre etmeden \u00f6nce baz\u0131 temel ayarlamalar\u0131 yapman\u0131z gerekmektedir.<\/p>\n<h4>DigitalOcean Hesab\u0131<\/h4>\n<p>Bu serinin bir par\u00e7as\u0131 olarak, DigitalOcean hesab\u0131n\u0131z\u0131n oldu\u011funu varsay\u0131yoruz. Uygulaman\u0131z\u0131 daha sonra bir DigitalOcean Droplet&#8217;ine veya App Platform&#8217;a da\u011f\u0131tabilirsiniz.<\/p>\n<h4>Postmark Hesab\u0131 Olu\u015fturma ve Ayarlar\u0131<\/h4>\n<p>1.  <strong>Postmark Hesab\u0131 Olu\u015fturma:<\/strong> Postmark web sitesine gidin ve yeni bir hesap olu\u015fturun. Genellikle ilk ay \u00fccretsiz kredi veya deneme s\u00fcresi sunarlar.<br \/>\n2.  <strong>Sunucu Olu\u015fturma:<\/strong> Hesab\u0131n\u0131zda oturum a\u00e7t\u0131ktan sonra bir &#8220;Server&#8221; (Sunucu) olu\u015fturman\u0131z gerekecektir. Bu sunucu, e-postalar\u0131n\u0131z\u0131 g\u00f6nderece\u011finiz ortam\u0131 temsil eder. Her sunucunun kendi API anahtar\u0131 ve ayarlar\u0131 bulunur.<br \/>\n3.  <strong>G\u00f6nderen \u0130mzas\u0131 Do\u011frulama (Sender Signature Verification):<\/strong> E-postalar\u0131 g\u00f6nderece\u011finiz e-posta adresini veya alan ad\u0131n\u0131 do\u011frulaman\u0131z gerekmektedir. Bu, Postmark&#8217;\u0131n e-postalar\u0131 sizin ad\u0131n\u0131za g\u00f6ndermesine izin verdi\u011finizi ve spam olarak i\u015faretlenmemelerini sa\u011flamak i\u00e7in kritik bir ad\u0131md\u0131r.<br \/>\n    *   Bir e-posta adresi i\u00e7in do\u011frulama yap\u0131yorsan\u0131z, Postmark size bir do\u011frulama e-postas\u0131 g\u00f6nderecektir.<br \/>\n    *   Bir alan ad\u0131 i\u00e7in do\u011frulama yap\u0131yorsan\u0131z (ki bu \u00fcretim ortamlar\u0131 i\u00e7in \u00f6nerilir), alan ad\u0131n\u0131z\u0131n DNS kay\u0131tlar\u0131na belirli TXT ve MX kay\u0131tlar\u0131 eklemeniz istenecektir. Bu i\u015flem, e-postalar\u0131n\u0131z\u0131n DMARC, DKIM ve SPF gibi kimlik do\u011frulama standartlar\u0131na uygun olmas\u0131n\u0131 sa\u011flar.<br \/>\n4.  <strong>API Token&#8217;\u0131 Alma:<\/strong> Olu\u015fturdu\u011funuz sunucunun ayarlar\u0131na gidin. Burada &#8220;API Tokens&#8221; b\u00f6l\u00fcm\u00fcnde bir sunucu API token&#8217;\u0131 bulacaks\u0131n\u0131z. Bu token, Flask uygulaman\u0131z\u0131n Postmark API&#8217;sine kimlik do\u011frulamas\u0131 yaparak istek g\u00f6ndermesi i\u00e7in kullan\u0131lacakt\u0131r. <strong>Bu token&#8217;\u0131 g\u00fcvende tutun ve asla a\u00e7\u0131k kaynak kodunuza dahil etmeyin.<\/strong><\/p>\n<h4>Flask Uygulama Ortam\u0131n\u0131n Haz\u0131rlanmas\u0131<\/h4>\n<p>1.  <strong>Python Kurulumu:<\/strong> Sisteminizde Python 3&#8217;\u00fcn kurulu oldu\u011fundan emin olun.<br \/>\n2.  <strong>Sanal Ortam Olu\u015fturma:<\/strong> Projenizin ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 izole etmek i\u00e7in bir sanal ortam olu\u015fturmak en iyi uygulamad\u0131r.<\/p>\n<pre><code class=\"language-bash\">python3 -m venv venv\n    source venv\/bin\/activate # Linux\/macOS\n    # venv\\Scripts\\activate # Windows<\/code><\/pre>\n<p>3.  <strong>Gerekli K\u00fct\u00fcphaneleri Y\u00fckleme:<\/strong> Flask uygulaman\u0131z\u0131 ve Postmark API ile ileti\u015fim kurmak i\u00e7in gerekli k\u00fct\u00fcphaneleri y\u00fckleyin.<\/p>\n<pre><code class=\"language-bash\">pip install Flask python-dotenv requests<\/code><\/pre>\n<p>    *   <code>Flask<\/code>: Web \u00e7er\u00e7evesi.<br \/>\n    *   <code>python-dotenv<\/code>: Ortam de\u011fi\u015fkenlerini <code>.env<\/code> dosyas\u0131ndan y\u00fcklemek i\u00e7in. API anahtarlar\u0131n\u0131z\u0131 ve di\u011fer hassas bilgileri g\u00fcvende tutmak i\u00e7in \u00f6nemlidir.<br \/>\n    *   <code>requests<\/code>: Postmark&#8217;\u0131n REST API&#8217;sine HTTP istekleri g\u00f6ndermek i\u00e7in.<\/p>\n<p>4.  <strong>Temel Flask Uygulama Yap\u0131s\u0131:<\/strong> Proje dizininizde <code>app.py<\/code> ve <code>.env<\/code> ad\u0131nda dosyalar olu\u015fturun.<\/p>\n<pre><code class=\"language-\">my_flask_app\/\n    \u251c\u2500\u2500 venv\/\n    \u251c\u2500\u2500 .env\n    \u2514\u2500\u2500 app.py<\/code><\/pre>\n<h3>Postmark&#8217;\u0131 Flask Uygulaman\u0131za Entegre Etme<\/h3>\n<p>\u015eimdi s\u0131ra geldi Postmark&#8217;\u0131 Flask uygulamam\u0131zla konu\u015fturmaya. API anahtar\u0131m\u0131z\u0131 g\u00fcvenli bir \u015fekilde saklayacak, basit e-postalar g\u00f6nderecek ve Postmark&#8217;\u0131n \u015fablon yeteneklerini kullanaca\u011f\u0131z.<\/p>\n<h4>Ortam De\u011fi\u015fkenlerini Y\u00f6netme<\/h4>\n<p>Hassas bilgileri (API anahtarlar\u0131 gibi) do\u011frudan kodunuza yazmak yerine ortam de\u011fi\u015fkenleri arac\u0131l\u0131\u011f\u0131yla y\u00f6netmek g\u00fcvenlik a\u00e7\u0131s\u0131ndan kritik \u00f6neme sahiptir. <code>python-dotenv<\/code> k\u00fct\u00fcphanesi bu konuda bize yard\u0131mc\u0131 olur.<\/p>\n<p><code>.env<\/code> dosyan\u0131z\u0131n i\u00e7eri\u011fi \u015f\u00f6yle olmal\u0131d\u0131r:<\/p>\n<pre><code class=\"language-dotenv\">POSTMARK_API_TOKEN=\"YOUR_POSTMARK_SERVER_API_TOKEN\"\nPOSTMARK_SENDER_EMAIL=\"sender@yourdomain.com\"\n<h2>E\u011fer Postmark \u015fablonlar\u0131n\u0131 kullanacaksan\u0131z<\/h2>\nPOSTMARK_TEMPLATE_WELCOME_ALIAS=\"welcome-email\"\nPOSTMARK_TEMPLATE_PASSWORD_RESET_ALIAS=\"password-reset\"<\/code><\/pre>\n<p>*   <code>YOUR_POSTMARK_SERVER_API_TOKEN<\/code>: Postmark hesab\u0131n\u0131zdan ald\u0131\u011f\u0131n\u0131z API token&#8217;\u0131d\u0131r.<br \/>\n*   <code>sender@yourdomain.com<\/code>: Postmark&#8217;ta do\u011frulad\u0131\u011f\u0131n\u0131z g\u00f6nderen e-posta adresinizdir.<\/p>\n<p><code>app.py<\/code> dosyan\u0131zda bu de\u011fi\u015fkenleri y\u00fcklemek i\u00e7in:<\/p>\n<pre><code class=\"language-python\">import os\nfrom dotenv import load_dotenv\n\nload_dotenv() # .env dosyas\u0131ndaki de\u011fi\u015fkenleri y\u00fckler\n\nPOSTMARK_API_TOKEN = os.getenv(\"POSTMARK_API_TOKEN\")\nPOSTMARK_SENDER_EMAIL = os.getenv(\"POSTMARK_SENDER_EMAIL\")\nPOSTMARK_TEMPLATE_WELCOME_ALIAS = os.getenv(\"POSTMARK_TEMPLATE_WELCOME_ALIAS\")\nPOSTMARK_TEMPLATE_PASSWORD_RESET_ALIAS = os.getenv(\"POSTMARK_TEMPLATE_PASSWORD_RESET_ALIAS\")\n\nif not all([POSTMARK_API_TOKEN, POSTMARK_SENDER_EMAIL]):\n    raise ValueError(\"Postmark API Token and Sender Email must be set in .env file.\")<\/code><\/pre>\n<h4>Basit Bir E-posta G\u00f6nderme (Metin veya HTML)<\/h4>\n<p>Postmark API&#8217;sine <code>requests<\/code> k\u00fct\u00fcphanesi ile bir POST iste\u011fi g\u00f6ndererek e-posta g\u00f6nderebiliriz.<\/p>\n<pre><code class=\"language-python\">import requests\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\n\n<h2>... (dotenv y\u00fckleme ve ortam de\u011fi\u015fkenleri yukar\u0131da oldu\u011fu gibi) ...<\/h2>\n\nPOSTMARK_API_BASE_URL = \"https:\/\/api.postmarkapp.com\/email\"\n\ndef send_simple_email(to_email, subject, text_body=None, html_body=None):\n    headers = {\n        \"Accept\": \"application\/json\",\n        \"Content-Type\": \"application\/json\",\n        \"X-Postmark-Server-Token\": POSTMARK_API_TOKEN,\n    }\n\n    payload = {\n        \"From\": POSTMARK_SENDER_EMAIL,\n        \"To\": to_email,\n        \"Subject\": subject,\n    }\n    if text_body:\n        payload[\"TextBody\"] = text_body\n    if html_body:\n        payload[\"HtmlBody\"] = html_body\n    \n    # E\u011fer hem TextBody hem de HtmlBody belirtilmediyse hata ver\n    if not text_body and not html_body:\n        raise ValueError(\"Either text_body or html_body must be provided.\")\n\n    try:\n        response = requests.post(POSTMARK_API_BASE_URL, headers=headers, json=payload)\n        response.raise_for_status() # HTTP hatalar\u0131 i\u00e7in istisna f\u0131rlat\n        return response.json()\n    except requests.exceptions.RequestException as e:\n        print(f\"E-posta g\u00f6nderme hatas\u0131: {e}\")\n        return {\"error\": str(e)}\n\n@app.route(\"\/send-test-email\", methods=[\"POST\"])\ndef send_test_email_route():\n    data = request.get_json()\n    to_email = data.get(\"to_email\")\n    subject = data.get(\"subject\", \"Test E-postas\u0131\")\n    text_body = data.get(\"text_body\", \"Bu bir test e-postas\u0131d\u0131r.\")\n    html_body = data.get(\"html_body\")\n\n    if not to_email:\n        return jsonify({\"message\": \"Al\u0131c\u0131 e-postas\u0131 gerekli\"}), 400\n\n    result = send_simple_email(to_email, subject, text_body, html_body)\n    if \"error\" in result:\n        return jsonify({\"message\": \"E-posta g\u00f6nderilemedi\", \"details\": result[\"error\"]}), 500\n    \n    return jsonify({\"message\": \"E-posta ba\u015far\u0131yla g\u00f6nderildi\", \"details\": result}), 200\n\nif __name__ == \"__main__\":\n    app.run(debug=True)<\/code><\/pre>\n<p>Bu kod par\u00e7as\u0131, <code>send_simple_email<\/code> ad\u0131nda bir yard\u0131mc\u0131 fonksiyon tan\u0131mlar ve bu fonksiyonu <code>requests<\/code> kullanarak Postmark API&#8217;sine bir POST iste\u011fi g\u00f6ndermek i\u00e7in kullan\u0131r. <code>send_test_email_route<\/code> ad\u0131ndaki Flask rotas\u0131 ise bir API endpoint&#8217;i olarak hizmet verir ve gelen iste\u011fe g\u00f6re e-posta g\u00f6nderir.<\/p>\n<p><strong>Test Etme:<\/strong><\/p>\n<p>Uygulamay\u0131 \u00e7al\u0131\u015ft\u0131r\u0131n: <code>python app.py<\/code><\/p>\n<p>Bir POST iste\u011fi g\u00f6nderin (\u00f6rne\u011fin Postman, Insomnia veya <code>curl<\/code> ile):<\/p>\n<pre><code class=\"language-bash\">curl -X POST -H \"Content-Type: application\/json\" -d '{\n    \"to_email\": \"recipient@example.com\",\n    \"subject\": \"Flask'tan Postmark Testi\",\n    \"text_body\": \"Merhaba, bu Flask uygulaman\u0131zdan g\u00f6nderilen bir test e-postas\u0131d\u0131r.\"\n}' http:\/\/127.0.0.1:5000\/send-test-email<\/code><\/pre>\n<h4>Postmark \u015eablonlar\u0131 ile E-posta G\u00f6nderme<\/h4>\n<p>Postmark&#8217;\u0131n en g\u00fc\u00e7l\u00fc \u00f6zelliklerinden biri, dinamik i\u00e7erik ekleyebilece\u011finiz \u00f6nceden tasarlanm\u0131\u015f e-posta \u015fablonlar\u0131 kullanma yetene\u011fidir. Bu, e-postalar\u0131n\u0131z\u0131n tutarl\u0131 bir tasar\u0131ma sahip olmas\u0131n\u0131 ve uygulaman\u0131zdan ayr\u0131\u015ft\u0131rma mant\u0131\u011f\u0131n\u0131 basitle\u015ftirmeyi sa\u011flar.<\/p>\n<p><strong>Postmark&#8217;ta \u015eablon Olu\u015fturma:<\/strong><\/p>\n<p>1.  Postmark hesab\u0131n\u0131za giri\u015f yap\u0131n.<br \/>\n2.  \u0130lgili sunucunuza gidin.<br \/>\n3.  &#8220;Templates&#8221; (\u015eablonlar) sekmesine t\u0131klay\u0131n.<br \/>\n4.  &#8220;Create Template&#8221; (\u015eablon Olu\u015ftur) d\u00fc\u011fmesine t\u0131klay\u0131n.<br \/>\n5.  Bir \u015fablon ad\u0131 ve iste\u011fe ba\u011fl\u0131 olarak bir &#8220;Template Alias&#8221; (\u015eablon Takma Ad\u0131) belirleyin. Takma ad, API \u00e7a\u011fr\u0131lar\u0131nda \u015fablonu kimliklendirmek i\u00e7in kullan\u0131\u015fl\u0131d\u0131r. \u00d6rne\u011fin, <code>welcome-email<\/code> veya <code>password-reset<\/code>.<br \/>\n6.  \u015eablonunuzun HTML ve\/veya metin i\u00e7eri\u011fini tasarlay\u0131n. Postmark&#8217;\u0131n \u015fablon dili Handlebars&#8217;a benzer. Dinamik veriler i\u00e7in <code>{{name}}<\/code> veya <code>{{user.first_name}}<\/code> gibi yer tutucular kullanabilirsiniz.<\/p>\n<p>\u00d6rnek bir ho\u015f geldin \u015fablonu (HTML):<\/p>\n<pre><code class=\"language-html\"><!DOCTYPE html>\n<html>\n<head>\n    <title>Ho\u015f Geldiniz!<\/title>\n<\/head>\n<body>\n    \n    <p>Kayd\u0131n\u0131z ba\u015far\u0131yla tamamland\u0131. Uygulamam\u0131z\u0131 ke\u015ffetmeye ba\u015flamak i\u00e7in a\u015fa\u011f\u0131daki ba\u011flant\u0131y\u0131 kullanabilirsiniz:<\/p>\n    <p><a href=\"{{ login_url }}\">Giri\u015f Yap<\/a><\/p>\n    <p>Sayg\u0131lar\u0131m\u0131zla,<br>Uygulama Ekibi<\/p>\n<\/body>\n<\/html><\/code><\/pre>\n<p>Flask taraf\u0131nda, bu \u015fablonu kullanmak i\u00e7in <code>\/email\/withTemplate<\/code> endpoint&#8217;ine istek g\u00f6nderece\u011fiz.<\/p>\n<pre><code class=\"language-python\"># ... (\u00f6nceki kodlar) ...\n\nPOSTMARK_TEMPLATE_API_URL = \"https:\/\/api.postmarkapp.com\/email\/withTemplate\"\n\ndef send_templated_email(to_email, template_alias, template_model, subject=None):\n    headers = {\n        \"Accept\": \"application\/json\",\n        \"Content-Type\": \"application\/json\",\n        \"X-Postmark-Server-Token\": POSTMARK_API_TOKEN,\n    }\n\n    payload = {\n        \"From\": POSTMARK_SENDER_EMAIL,\n        \"To\": to_email,\n        \"TemplateAlias\": template_alias,\n        \"TemplateModel\": template_model,\n    }\n    \n    # E\u011fer \u015fablonun kendi konusu yoksa veya API'den konu belirtmek istiyorsak\n    if subject:\n        payload[\"Subject\"] = subject\n\n    try:\n        response = requests.post(POSTMARK_TEMPLATE_API_URL, headers=headers, json=payload)\n        response.raise_for_status()\n        return response.json()\n    except requests.exceptions.RequestException as e:\n        print(f\"\u015eablonlu e-posta g\u00f6nderme hatas\u0131: {e}\")\n        return {\"error\": str(e)}\n\n@app.route(\"\/send-welcome-email\", methods=[\"POST\"])\ndef send_welcome_email_route():\n    data = request.get_json()\n    to_email = data.get(\"to_email\")\n    user_name = data.get(\"user_name\", \"Kullan\u0131c\u0131\")\n    login_url = data.get(\"login_url\", \"https:\/\/your-app.com\/login\")\n\n    if not to_email:\n        return jsonify({\"message\": \"Al\u0131c\u0131 e-postas\u0131 gerekli\"}), 400\n\n    template_model = {\n        \"name\": user_name,\n        \"login_url\": login_url,\n        \"product_name\": \"Uygulaman\u0131z\" # \u015eablonda kullan\u0131labilecek ek veriler\n    }\n\n    # E\u011fer .env dosyas\u0131nda tan\u0131mlad\u0131ysak template alias'\u0131 kullan\n    if not POSTMARK_TEMPLATE_WELCOME_ALIAS:\n        return jsonify({\"message\": \"Ho\u015f geldin \u015fablonu takma ad\u0131 (.env) belirtilmemi\u015f\"}), 500\n\n    result = send_templated_email(to_email, POSTMARK_TEMPLATE_WELCOME_ALIAS, template_model)\n    if \"error\" in result:\n        return jsonify({\"message\": \"Ho\u015f geldin e-postas\u0131 g\u00f6nderilemedi\", \"details\": result[\"error\"]}), 500\n    \n    return jsonify({\"message\": \"Ho\u015f geldin e-postas\u0131 ba\u015far\u0131yla g\u00f6nderildi\", \"details\": result}), 200\n\nif __name__ == \"__main__\":\n    app.run(debug=True)<\/code><\/pre>\n<p>Bu \u00f6rnek, <code>send_templated_email<\/code> fonksiyonunu kullanarak Postmark&#8217;ta tan\u0131mlanm\u0131\u015f bir \u015fablonu nas\u0131l g\u00f6nderece\u011finizi g\u00f6sterir. <code>TemplateAlias<\/code> ile hangi \u015fablonun kullan\u0131laca\u011f\u0131n\u0131 belirtirken, <code>TemplateModel<\/code> ile \u015fablondaki yer tutuculara dinamik verileri iletiriz.<\/p>\n<h4>Yard\u0131mc\u0131 Fonksiyonlar\u0131 Mod\u00fcler Hale Getirme<\/h4>\n<p>E-posta g\u00f6nderme mant\u0131\u011f\u0131n\u0131 ana <code>app.py<\/code> dosyas\u0131ndan ay\u0131r\u0131p ayr\u0131 bir mod\u00fcle ta\u015f\u0131mak, uygulaman\u0131z b\u00fcy\u00fcd\u00fck\u00e7e kodunuzu daha d\u00fczenli ve s\u00fcrd\u00fcr\u00fclebilir hale getirecektir.<\/p>\n<p>\u00d6rne\u011fin, <code>email_service.py<\/code> ad\u0131nda yeni bir dosya olu\u015fturabiliriz:<\/p>\n<pre><code class=\"language-python\"># email_service.py\nimport os\nimport requests\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\nPOSTMARK_API_TOKEN = os.getenv(\"POSTMARK_API_TOKEN\")\nPOSTMARK_SENDER_EMAIL = os.getenv(\"POSTMARK_SENDER_EMAIL\")\n\nPOSTMARK_API_BASE_URL = \"https:\/\/api.postmarkapp.com\/email\"\nPOSTMARK_TEMPLATE_API_URL = \"https:\/\/api.postmarkapp.com\/email\/withTemplate\"\n\nif not all([POSTMARK_API_TOKEN, POSTMARK_SENDER_EMAIL]):\n    raise ValueError(\"Postmark API Token and Sender Email must be set in .env file.\")\n\ndef _postmark_request(url, payload):\n    headers = {\n        \"Accept\": \"application\/json\",\n        \"Content-Type\": \"application\/json\",\n        \"X-Postmark-Server-Token\": POSTMARK_API_TOKEN,\n    }\n    try:\n        response = requests.post(url, headers=headers, json=payload)\n        response.raise_for_status()\n        return response.json()\n    except requests.exceptions.RequestException as e:\n        print(f\"Postmark API hatas\u0131: {e}\")\n        return {\"error\": str(e)}\n\ndef send_simple_email(to_email, subject, text_body=None, html_body=None):\n    payload = {\n        \"From\": POSTMARK_SENDER_EMAIL,\n        \"To\": to_email,\n        \"Subject\": subject,\n    }\n    if text_body:\n        payload[\"TextBody\"] = text_body\n    if html_body:\n        payload[\"HtmlBody\"] = html_body\n    \n    if not text_body and not html_body:\n        raise ValueError(\"Either text_body or html_body must be provided.\")\n\n    return _postmark_request(POSTMARK_API_BASE_URL, payload)\n\ndef send_templated_email(to_email, template_alias, template_model, subject=None):\n    payload = {\n        \"From\": POSTMARK_SENDER_EMAIL,\n        \"To\": to_email,\n        \"TemplateAlias\": template_alias,\n        \"TemplateModel\": template_model,\n    }\n    if subject:\n        payload[\"Subject\"] = subject\n    \n    return _postmark_request(POSTMARK_TEMPLATE_API_URL, payload)<\/code><\/pre>\n<p>\u015eimdi <code>app.py<\/code> dosyan\u0131zda bu fonksiyonlar\u0131 i\u00e7e aktarabilir ve kullanabilirsiniz:<\/p>\n<pre><code class=\"language-python\"># app.py\nfrom flask import Flask, request, jsonify\nimport os\nfrom dotenv import load_dotenv\nfrom email_service import send_simple_email, send_templated_email\n\nload_dotenv()\n\napp = Flask(__name__)\n\n<h2>Ortam de\u011fi\u015fkenlerini do\u011frudan email_service'den \u00e7ekebiliriz veya burada da tan\u0131mlayabiliriz.<\/h2>\n<h2>Kolayl\u0131k a\u00e7\u0131s\u0131ndan burada da tutal\u0131m ki route'lar direkt eri\u015febilsin.<\/h2>\nPOSTMARK_TEMPLATE_WELCOME_ALIAS = os.getenv(\"POSTMARK_TEMPLATE_WELCOME_ALIAS\")\nPOSTMARK_TEMPLATE_PASSWORD_RESET_ALIAS = os.getenv(\"POSTMARK_TEMPLATE_PASSWORD_RESET_ALIAS\")\n\n@app.route(\"\/send-test-email\", methods=[\"POST\"])\ndef send_test_email_route():\n    data = request.get_json()\n    to_email = data.get(\"to_email\")\n    subject = data.get(\"subject\", \"Test E-postas\u0131\")\n    text_body = data.get(\"text_body\", \"Bu bir test e-postas\u0131d\u0131r.\")\n    html_body = data.get(\"html_body\")\n\n    if not to_email:\n        return jsonify({\"message\": \"Al\u0131c\u0131 e-postas\u0131 gerekli\"}), 400\n\n    result = send_simple_email(to_email, subject, text_body, html_body)\n    if \"error\" in result:\n        return jsonify({\"message\": \"E-posta g\u00f6nderilemedi\", \"details\": result[\"error\"]}), 500\n    \n    return jsonify({\"message\": \"E-posta ba\u015far\u0131yla g\u00f6nderildi\", \"details\": result}), 200\n\n@app.route(\"\/send-welcome-email\", methods=[\"POST\"])\ndef send_welcome_email_route():\n    data = request.get_json()\n    to_email = data.get(\"to_email\")\n    user_name = data.get(\"user_name\", \"Kullan\u0131c\u0131\")\n    login_url = data.get(\"login_url\", \"https:\/\/your-app.com\/login\")\n\n    if not to_email:\n        return jsonify({\"message\": \"Al\u0131c\u0131 e-postas\u0131 gerekli\"}), 400\n\n    template_model = {\n        \"name\": user_name,\n        \"login_url\": login_url,\n        \"product_name\": \"Uygulaman\u0131z\"\n    }\n\n    if not POSTMARK_TEMPLATE_WELCOME_ALIAS:\n        return jsonify({\"message\": \"Ho\u015f geldin \u015fablonu takma ad\u0131 (.env) belirtilmemi\u015f\"}), 500\n\n    result = send_templated_email(to_email, POSTMARK_TEMPLATE_WELCOME_ALIAS, template_model)\n    if \"error\" in result:\n        return jsonify({\"message\": \"Ho\u015f geldin e-postas\u0131 g\u00f6nderilemedi\", \"details\": result[\"error\"]}), 500\n    \n    return jsonify({\"message\": \"Ho\u015f geldin e-postas\u0131 ba\u015far\u0131yla g\u00f6nderildi\", \"details\": result}), 200\n\nif __name__ == \"__main__\":\n    app.run(debug=True)<\/code><\/pre>\n<p>Bu mod\u00fcler yap\u0131, kodunuzu daha okunabilir, test edilebilir ve y\u00f6netilebilir hale getirir.<\/p>\n<h3>En \u0130yi Uygulamalar ve Dikkate Al\u0131nmas\u0131 Gerekenler<\/h3>\n<p>Flask uygulaman\u0131za Postmark entegrasyonunu yaparken, performans\u0131, g\u00fcvenli\u011fi ve g\u00fcvenilirli\u011fi art\u0131rmak i\u00e7in baz\u0131 en iyi uygulamalar\u0131 g\u00f6z \u00f6n\u00fcnde bulundurmak \u00f6nemlidir.<\/p>\n<h4>G\u00fcvenlik<\/h4>\n<p>*   <strong>API Anahtarlar\u0131n\u0131 G\u00fcvende Tutma:<\/strong> Postmark API token&#8217;\u0131n\u0131z, e-posta g\u00f6nderme yetkisi veren hassas bir bilgidir. Asla do\u011frudan kaynak kodunuza yazmay\u0131n veya s\u00fcr\u00fcm kontrol sistemlerine (git gibi) commit etmeyin. <code>.env<\/code> dosyalar\u0131 kullanmak, yerel geli\u015ftirme i\u00e7in iyi bir \u00e7\u00f6z\u00fcmd\u00fcr. \u00dcretim ortam\u0131nda DigitalOcean App Platform&#8217;da &#8220;Secrets&#8221; veya Droplet&#8217;lerde ortam de\u011fi\u015fkenleri olarak ayarlamal\u0131s\u0131n\u0131z.<br \/>\n*   <strong>SSL\/TLS Kullan\u0131m\u0131:<\/strong> <code>requests<\/code> k\u00fct\u00fcphanesi varsay\u0131lan olarak HTTPS kullan\u0131r, bu da Postmark API&#8217;sine g\u00f6nderilen verilerin \u015fifrelenmesini sa\u011flar. Bu, hassas bilgilerin (al\u0131c\u0131 e-postalar\u0131, \u015fablon modelleri) a\u011f \u00fczerinden g\u00fcvenli bir \u015fekilde iletilmesini garanti eder.<\/p>\n<h4>Asenkron E-posta G\u00f6nderme<\/h4>\n<p>E-posta g\u00f6nderme i\u015flemi, bir HTTP iste\u011fi ve harici bir servisle ileti\u015fim gerektirdi\u011finden, bazen gecikmelere neden olabilir. Bir kullan\u0131c\u0131 bir eylem ger\u00e7ekle\u015ftirdi\u011finde (\u00f6rne\u011fin kay\u0131t oldu\u011funda) ve uygulaman\u0131z\u0131n hemen bir e-posta g\u00f6ndermesi gerekti\u011finde, bu senkronize i\u015flem kullan\u0131c\u0131n\u0131n iste\u011fini bloklayabilir ve yan\u0131t s\u00fcresini uzatabilir.<\/p>\n<p>\u00dcretim ortamlar\u0131nda, e-posta g\u00f6nderme gibi zaman al\u0131c\u0131 i\u015flemleri asenkron olarak y\u00fcr\u00fctmek en iyi uygulamad\u0131r. Bunun i\u00e7in birka\u00e7 y\u00f6ntem vard\u0131r:<\/p>\n<p>*   <strong>G\u00f6rev Kuyruklar\u0131 (Task Queues):<\/strong> Celery, Redis veya RabbitMQ gibi bir mesaj broker&#8217;\u0131 ile birlikte kullan\u0131ld\u0131\u011f\u0131nda, e-posta g\u00f6nderme g\u00f6revlerini arka plana atman\u0131n en yayg\u0131n ve sa\u011flam yoludur. Flask uygulaman\u0131z bir e-posta g\u00f6nderme iste\u011fi ald\u0131\u011f\u0131nda, bu g\u00f6revi kuyru\u011fa ekler ve hemen kullan\u0131c\u0131ya yan\u0131t verir. Ayr\u0131 bir Celery worker s\u00fcreci kuyruktaki g\u00f6revleri al\u0131r ve e-postalar\u0131 g\u00f6nderir. DigitalOcean Droplet&#8217;leri, bu t\u00fcr bir mimariyi bar\u0131nd\u0131rmak i\u00e7in m\u00fckemmeldir.<br \/>\n*   <strong>Basit Arka Plan S\u00fcre\u00e7leri\/Threading:<\/strong> Daha k\u00fc\u00e7\u00fck uygulamalar i\u00e7in Python&#8217;\u0131n <code>threading<\/code> mod\u00fcl\u00fcn\u00fc veya basit bir arka plan s\u00fcreci olu\u015fturmay\u0131 d\u00fc\u015f\u00fcnebilirsiniz. Ancak bu y\u00f6ntemler, hata y\u00f6netimi ve \u00f6l\u00e7eklenebilirlik a\u00e7\u0131s\u0131ndan g\u00f6rev kuyruklar\u0131 kadar g\u00fc\u00e7l\u00fc de\u011fildir.<\/p>\n<p><strong>\u00d6rnek (Basit Threading ile &#8211; \u00dcretim i\u00e7in \u00f6nerilmez, sadece konsept g\u00f6sterimi):<\/strong><\/p>\n<pre><code class=\"language-python\"># app.py\n<h2>... (\u00f6nceki kodlar) ...<\/h2>\nimport threading\nfrom email_service import send_templated_email # veya send_simple_email\n\ndef send_email_async(to_email, template_alias, template_model):\n    # Bu fonksiyonu ayr\u0131 bir thread'de \u00e7al\u0131\u015ft\u0131rmak i\u00e7in\n    result = send_templated_email(to_email, template_alias, template_model)\n    if \"error\" in result:\n        print(f\"Async e-posta g\u00f6nderme hatas\u0131: {result['error']}\")\n    else:\n        print(f\"Async e-posta ba\u015far\u0131yla g\u00f6nderildi: {result}\")\n\n@app.route(\"\/register\", methods=[\"POST\"])\ndef register_user():\n    data = request.get_json()\n    user_email = data.get(\"email\")\n    user_name = data.get(\"name\")\n\n    if not user_email or not user_name:\n        return jsonify({\"message\": \"E-posta ve isim gerekli\"}), 400\n\n    # Kullan\u0131c\u0131y\u0131 veritaban\u0131na kaydetme vb. i\u015flemler burada yap\u0131l\u0131r\n    # ...\n\n    template_model = {\n        \"name\": user_name,\n        \"login_url\": \"https:\/\/your-app.com\/login\"\n    }\n\n    # E-postay\u0131 asenkron olarak g\u00f6nder\n    email_thread = threading.Thread(target=send_email_async, \n                                    args=(user_email, POSTMARK_TEMPLATE_WELCOME_ALIAS, template_model))\n    email_thread.start()\n\n    return jsonify({\"message\": \"Kay\u0131t ba\u015far\u0131l\u0131, ho\u015f geldin e-postas\u0131 g\u00f6nderiliyor.\"}), 201\n\n<h2>... (di\u011fer kodlar) ...<\/code><\/pre>\n<\/h2>\n<p>Bu yakla\u015f\u0131m, kullan\u0131c\u0131ya hemen yan\u0131t vermenizi sa\u011flarken, e-posta g\u00f6nderme i\u015flemini arka planda y\u00fcr\u00fct\u00fcr. Ancak <code>threading<\/code> mod\u00fcl\u00fc, uygulaman\u0131z\u0131n \u00f6l\u00e7eklenebilirli\u011fi ve hata tolerans\u0131 i\u00e7in yetersiz kalabilir. Ger\u00e7ek \u00fcretim uygulamalar\u0131 i\u00e7in Celery gibi daha sa\u011flam \u00e7\u00f6z\u00fcmler d\u00fc\u015f\u00fcn\u00fclmelidir.<\/p>\n<h4>Hata \u0130\u015fleme ve G\u00fcnl\u00fck Kayd\u0131 (Logging)<\/h4>\n<p>E-posta g\u00f6nderme i\u015flemleri ba\u015far\u0131s\u0131z olabilir (a\u011f sorunlar\u0131, Postmark API hatas\u0131, yanl\u0131\u015f al\u0131c\u0131 adresi vb.). Bu durumlar\u0131 do\u011fru bir \u015fekilde ele almak \u00f6nemlidir:<\/p>\n<p>*   <strong>API Yan\u0131tlar\u0131n\u0131 Kontrol Etme:<\/strong> Postmark API&#8217;sinden d\u00f6nen yan\u0131tlar\u0131 her zaman kontrol edin. Ba\u015far\u0131l\u0131 yan\u0131tlar genellikle bir <code>MessageID<\/code> ve <code>ErrorCode<\/code> (0 ise ba\u015far\u0131) i\u00e7erir. Hata durumunda, <code>ErrorCode<\/code> ve <code>Message<\/code> alanlar\u0131 sorunu anlaman\u0131za yard\u0131mc\u0131 olur.<br \/>\n*   <strong>Denemeler (Retries):<\/strong> Ge\u00e7ici a\u011f sorunlar\u0131 veya API&#8217;deki anl\u0131k kesintiler nedeniyle ba\u015far\u0131s\u0131z olan istekler i\u00e7in tekrar deneme mekanizmas\u0131 uygulamak faydal\u0131 olabilir (\u00f6rne\u011fin, belirli bir gecikmeyle 3 kez deneme).<br \/>\n*   <strong>G\u00fcnl\u00fck Kayd\u0131:<\/strong> E-posta g\u00f6nderme olaylar\u0131n\u0131 ve \u00f6zellikle hatalar\u0131 uygulaman\u0131z\u0131n g\u00fcnl\u00fcklerine kaydedin. Bu, sorun giderme ve e-posta ak\u0131\u015f\u0131n\u0131z\u0131n sa\u011fl\u0131\u011f\u0131n\u0131 izlemek i\u00e7in kritik \u00f6neme sahiptir. Python&#8217;\u0131n yerle\u015fik <code>logging<\/code> mod\u00fcl\u00fcn\u00fc kullanabilirsiniz.<\/p>\n<pre><code class=\"language-python\">import logging\n\nlogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')\n\n<h2>... send_simple_email veya send_templated_email fonksiyonlar\u0131nda ...<\/h2>\n    try:\n        response = requests.post(url, headers=headers, json=payload)\n        response.raise_for_status()\n        logging.info(f\"E-posta ba\u015far\u0131yla g\u00f6nderildi: {response.json()}\")\n        return response.json()\n    except requests.exceptions.RequestException as e:\n        logging.error(f\"Postmark API hatas\u0131: {e} - Payload: {payload}\")\n        return {\"error\": str(e)}<\/code><\/pre>\n<h4>E-posta \u015eablonlar\u0131 ve Tasar\u0131m<\/h4>\n<p>*   <strong>Duyarl\u0131 Tasar\u0131m:<\/strong> E-postalar\u0131n\u0131z\u0131n farkl\u0131 cihazlarda (mobil, tablet, masa\u00fcst\u00fc) iyi g\u00f6r\u00fcnmesini sa\u011flamak i\u00e7in duyarl\u0131 (responsive) \u015fablonlar kullan\u0131n. Postmark&#8217;\u0131n kendi \u015fablon d\u00fczenleyicisi ve \u00f6nizleme ara\u00e7lar\u0131 bu konuda yard\u0131mc\u0131 olabilir.<br \/>\n*   <strong>Ki\u015fiselle\u015ftirme:<\/strong> \u015eablonlardaki dinamik yer tutucular\u0131 kullanarak e-postalar\u0131 al\u0131c\u0131ya \u00f6zel hale getirin. Bu, kullan\u0131c\u0131 etkile\u015fimini art\u0131r\u0131r.<br \/>\n*   <strong>Test Etme:<\/strong> E-postalar\u0131 farkl\u0131 e-posta istemcilerinde (Gmail, Outlook, Apple Mail vb.) test edin. Postmark&#8217;\u0131n sundu\u011fu &#8220;Test&#8221; \u00f6zelli\u011fi veya Litmus\/Email on Acid gibi ara\u00e7lar bu konuda faydal\u0131d\u0131r.<\/p>\n<h4>Webhooks ile Geri Bildirim<\/h4>\n<p>Postmark, e-postalar\u0131n\u0131z\u0131n teslimat durumu, a\u00e7\u0131lma, t\u0131klama, spam \u015fikayetleri veya geri d\u00f6nme (bounce) gibi olaylar hakk\u0131nda uygulaman\u0131za bilgi g\u00f6ndermek i\u00e7in webhooks kullan\u0131r.<\/p>\n<p>*   <strong>Webhook Endpoint&#8217;i Olu\u015fturma:<\/strong> Flask uygulaman\u0131zda Postmark&#8217;tan gelen POST isteklerini dinleyecek bir API endpoint&#8217;i olu\u015fturun.<br \/>\n*   <strong>Postmark&#8217;ta Webhook Ayarlama:<\/strong> Postmark sunucunuzun ayarlar\u0131nda, bu endpoint URL&#8217;sini kaydedin ve hangi olaylar i\u00e7in bildirim almak istedi\u011finizi se\u00e7in.<br \/>\n*   <strong>Gelen Verileri \u0130\u015fleme:<\/strong> Flask endpoint&#8217;iniz, Postmark&#8217;tan gelen JSON y\u00fck\u00fcn\u00fc alacak ve buna g\u00f6re i\u015flem yapacakt\u0131r (\u00f6rne\u011fin, bir e-postan\u0131n a\u00e7\u0131ld\u0131\u011f\u0131n\u0131 veritaban\u0131na kaydetmek veya bir kullan\u0131c\u0131n\u0131n spam \u015fikayetini i\u015flemek).<\/p>\n<pre><code class=\"language-python\"># app.py\n<h2>... (\u00f6nceki kodlar) ...<\/h2>\n\n@app.route(\"\/postmark-webhook\", methods=[\"POST\"])\ndef postmark_webhook():\n    data = request.get_json()\n    event_type = data.get(\"RecordType\") # \"Bounce\", \"Open\", \"Click\", \"Delivery\" vb.\n\n    logging.info(f\"Postmark Webhook Olay\u0131 Al\u0131nd\u0131: {event_type} - MessageID: {data.get('MessageID')}\")\n    # Gelen veriyi i\u015fleme mant\u0131\u011f\u0131 burada yer al\u0131r\n    # \u00d6rne\u011fin, veritaban\u0131na kaydetme, kullan\u0131c\u0131ya bildirim g\u00f6nderme vb.\n\n    return jsonify({\"status\": \"success\"}), 200<\/code><\/pre>\n<p>Webhooks, e-posta ileti\u015fimlerinizin ger\u00e7ek zamanl\u0131 takibini otomatikle\u015ftirmek i\u00e7in g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r.<\/p>\n<h3>DigitalOcean \u00dczerinde Da\u011f\u0131t\u0131m<\/h3>\n<p>Flask uygulaman\u0131z\u0131 DigitalOcean \u00fczerinde da\u011f\u0131tmak, Postmark entegrasyonunuzun \u00fcretimde \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flamak i\u00e7in son ad\u0131md\u0131r.<\/p>\n<p>*   <strong>DigitalOcean App Platform:<\/strong> Flask uygulaman\u0131z\u0131 da\u011f\u0131tmak i\u00e7in en kolay yollardan biridir. Git deponuzu ba\u011flars\u0131n\u0131z, App Platform uygulaman\u0131z\u0131 otomatik olarak olu\u015fturur ve da\u011f\u0131t\u0131r. Ortam de\u011fi\u015fkenlerinizi (API token&#8217;lar\u0131 gibi) App Platform&#8217;un &#8220;Environment Variables&#8221; b\u00f6l\u00fcm\u00fcnde g\u00fcvenli bir \u015fekilde ayarlayabilirsiniz.<br \/>\n*   <strong>DigitalOcean Droplet (Sanal Sunucu):<\/strong> Daha fazla kontrol ve \u00f6zelle\u015ftirme istiyorsan\u0131z, bir Droplet olu\u015fturabilir ve uygulaman\u0131z\u0131 manuel olarak da\u011f\u0131tabilirsiniz. Bu genellikle Gunicorn gibi bir WSGI sunucusu ve Nginx gibi bir ters proxy kullanarak yap\u0131l\u0131r. Ortam de\u011fi\u015fkenlerinizi Droplet&#8217;in i\u015fletim sisteminde veya uygulaman\u0131z\u0131 ba\u015flatan betiklerde ayarlayabilirsiniz.<br \/>\n*   <strong>Veritaban\u0131 Hizmetleri:<\/strong> Uygulaman\u0131z\u0131n bir veritaban\u0131na ihtiyac\u0131 varsa, DigitalOcean&#8217;\u0131n Managed Databases hizmetlerini (PostgreSQL, MySQL, Redis) kullanabilirsiniz.<\/p>\n<p>Her iki da\u011f\u0131t\u0131m y\u00f6nteminde de, Postmark API token&#8217;\u0131n\u0131z\u0131n ve g\u00f6nderen e-posta adresinizin do\u011fru ortam de\u011fi\u015fkenleri olarak ayarland\u0131\u011f\u0131ndan emin olun.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Bu makalede, &#8220;12 Days of DigitalOcean&#8221; serisinin sekizinci g\u00fcn\u00fcnde, Postmark&#8217;\u0131 bir Flask uygulamas\u0131na nas\u0131l ba\u011flayaca\u011f\u0131m\u0131z\u0131 ayr\u0131nt\u0131l\u0131 olarak inceledik. Postmark&#8217;\u0131n y\u00fcksek teslim edilebilirlik, h\u0131z ve \u015fablonlama gibi avantajlar\u0131n\u0131, Flask&#8217;\u0131n hafif ve esnek yap\u0131s\u0131yla birle\u015ftirerek, g\u00fc\u00e7l\u00fc ve g\u00fcvenilir bir e-posta ileti\u015fim altyap\u0131s\u0131 olu\u015fturmay\u0131 \u00f6\u011frendik. Ortam de\u011fi\u015fkenlerini y\u00f6netmekten, basit ve \u015fablonlu e-postalar g\u00f6ndermeye, mod\u00fcler kod yap\u0131s\u0131 olu\u015fturmaya kadar bir\u00e7ok konuya de\u011findik. Ayr\u0131ca, g\u00fcvenlik, asenkron e-posta g\u00f6nderme, hata i\u015fleme ve DigitalOcean \u00fczerinde da\u011f\u0131t\u0131m gibi en iyi uygulamalar\u0131 ve \u00f6nemli hususlar\u0131 ele ald\u0131k.<\/p>\n<p>Art\u0131k Flask uygulaman\u0131z, kullan\u0131c\u0131lar\u0131n\u0131zla etkile\u015fim kurmak i\u00e7in Postmark&#8217;\u0131n g\u00fcc\u00fcnden yararlanarak profesyonel ve g\u00fcvenilir e-postalar g\u00f6nderebilir. Bu entegrasyon, uygulaman\u0131z\u0131n kullan\u0131c\u0131 deneyimini zenginle\u015ftirirken, e-posta g\u00f6nderiminin karma\u015f\u0131k y\u00f6nlerini sizin i\u00e7in basitle\u015ftirir. DigitalOcean&#8217;\u0131n esnek altyap\u0131s\u0131 sayesinde, bu t\u00fcr bir \u00e7\u00f6z\u00fcm\u00fc kolayca geli\u015ftirip \u00f6l\u00e7eklendirebilirsiniz. Uygulaman\u0131z\u0131n e-posta ihtiya\u00e7lar\u0131 i\u00e7in Postmark ve Flask kombinasyonunu kullanarak, kullan\u0131c\u0131lar\u0131n\u0131zla daha etkili bir \u015fekilde ba\u011flant\u0131 kurmaya haz\u0131rs\u0131n\u0131z.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"12 Days of DigitalOcean (Day 8) &#8211; Postmark&#8217;\u0131 Flask Uygulaman\u0131za Ba\u011flama\nDigitalOcean&#8217;\u0131n &#8220;12 Days of DigitalOcean&#8221; serisi, geli\u015ftiricilere bulut","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1401],"tags":[],"class_list":{"0":"post-31169","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-git","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>12 Days of DigitalOcean (Day 8) - Postmark&#039;\u0131 Flask Uygulaman\u0131za Ba\u011flama - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"12 Days of DigitalOcean (Day 8) - Postmark&#039;\u0131 Flask Uygulaman\u0131za Ba\u011flama\" \/>\n<meta property=\"og:description\" content=\"12 Days of DigitalOcean (Day 8) - Postmark&#039;\u0131 Flask Uygulaman\u0131za Ba\u011flama DigitalOcean&#039;\u0131n &quot;12 Days of DigitalOcean&quot; serisi, geli\u015ftiricilere bulut\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-06T13:41:40+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"22 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"12 Days of DigitalOcean (Day 8) &#8211; Postmark&#8217;\u0131 Flask Uygulaman\u0131za Ba\u011flama\",\"datePublished\":\"2025-10-06T13:41:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/\"},\"wordCount\":2897,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Git\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/\",\"name\":\"12 Days of DigitalOcean (Day 8) - Postmark'\u0131 Flask Uygulaman\u0131za Ba\u011flama - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-06T13:41:40+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"12 Days of DigitalOcean (Day 8) &#8211; Postmark&#8217;\u0131 Flask Uygulaman\u0131za Ba\u011flama\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"12 Days of DigitalOcean (Day 8) - Postmark'\u0131 Flask Uygulaman\u0131za Ba\u011flama - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/","og_locale":"tr_TR","og_type":"article","og_title":"12 Days of DigitalOcean (Day 8) - Postmark'\u0131 Flask Uygulaman\u0131za Ba\u011flama","og_description":"12 Days of DigitalOcean (Day 8) - Postmark'\u0131 Flask Uygulaman\u0131za Ba\u011flama DigitalOcean'\u0131n \"12 Days of DigitalOcean\" serisi, geli\u015ftiricilere bulut","og_url":"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-06T13:41:40+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"22 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"12 Days of DigitalOcean (Day 8) &#8211; Postmark&#8217;\u0131 Flask Uygulaman\u0131za Ba\u011flama","datePublished":"2025-10-06T13:41:40+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/"},"wordCount":2897,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Git"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/","url":"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/","name":"12 Days of DigitalOcean (Day 8) - Postmark'\u0131 Flask Uygulaman\u0131za Ba\u011flama - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-06T13:41:40+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/12-days-of-digitalocean-day-8-postmarki-flask-uygulamaniza-baglama\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"12 Days of DigitalOcean (Day 8) &#8211; Postmark&#8217;\u0131 Flask Uygulaman\u0131za Ba\u011flama"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31169","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=31169"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31169\/revisions"}],"predecessor-version":[{"id":31170,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31169\/revisions\/31170"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31169"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31169"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31169"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}