{"id":30287,"date":"2025-09-26T14:02:19","date_gmt":"2025-09-26T11:02:19","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/"},"modified":"2025-09-26T14:02:19","modified_gmt":"2025-09-26T11:02:19","slug":"guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/","title":{"rendered":"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi"},"content":{"rendered":"<p><body><br \/>\n  <main><\/p>\n<article>\n<header>\n        G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi<\/p>\n<p>E-posta y\u00f6netimini komut sat\u0131r\u0131na ta\u015f\u0131yarak verimlili\u011finizi art\u0131r\u0131n! Bu rehber, g\u00fcvenli bir Gmail CLI uygulamas\u0131n\u0131 ba\u015ftan sona nas\u0131l geli\u015ftirece\u011finizi ve \u00fcretime nas\u0131l ge\u00e7irece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131kl\u0131yor.<\/p>\n<\/header>\n<section>\n<h2>Neden G\u00fcvenli Bir Gmail CLI Uygulamas\u0131na \u0130htiya\u00e7 Duyar\u0131z?<\/h2>\n<p>Geli\u015ftiriciler, sistem y\u00f6neticileri ve otomasyon merakl\u0131lar\u0131 i\u00e7in komut sat\u0131r\u0131 aray\u00fczleri (CLI), g\u00fcnl\u00fck i\u015f ak\u0131\u015flar\u0131n\u0131 h\u0131zland\u0131rman\u0131n ve tekrarlayan g\u00f6revleri otomatikle\u015ftirmenin vazge\u00e7ilmez bir yoludur. Peki, e-posta y\u00f6netimi s\u00f6z konusu oldu\u011funda neden CLI kullanmal\u0131y\u0131z? Geleneksel web aray\u00fczleri veya masa\u00fcst\u00fc uygulamalar\u0131 elbette g\u00fc\u00e7l\u00fcd\u00fcr, ancak belirli senaryolarda CLI&#8217;n\u0131n sundu\u011fu esneklik ve h\u0131z rakipsiz olabilir.<\/p>\n<p>\u00d6rne\u011fin, bir sunucuda \u00e7al\u0131\u015fan bir uygulaman\u0131n belirli bir durumu hakk\u0131nda otomatik e-posta bildirimleri g\u00f6ndermesi gerekebilir. Ya da b\u00fcy\u00fck bir veri setini i\u015fledikten sonra sonu\u00e7lar\u0131 belli bir e-posta adresine iletmek isteyebilirsiniz. Belki de bir grup kullan\u0131c\u0131n\u0131n e-posta kutular\u0131n\u0131 toplu olarak y\u00f6netmek, belirli etiketleri uygulamak veya eski iletileri ar\u015fivlemek gibi operasyonel g\u00f6revleriniz vard\u0131r. Bu gibi durumlarda, grafiksel aray\u00fczlerin her ad\u0131m\u0131n\u0131 manuel olarak tekrarlamak yerine, birka\u00e7 sat\u0131r kodla i\u015fleri halleden bir CLI uygulamas\u0131 hayat kurtar\u0131c\u0131 olabilir.<\/p>\n<p>Ancak, e-posta gibi hassas bir veri kayna\u011f\u0131na eri\u015fim sa\u011flayan bir uygulama geli\u015ftirirken g\u00fcvenlik en \u00f6ncelikli konudur. E-postalar\u0131n\u0131z ki\u015fisel bilgiler, ticari s\u0131rlar veya kritik veriler i\u00e7erebilir. Bu nedenle, geli\u015ftirece\u011fimiz Gmail CLI uygulamas\u0131n\u0131n sadece i\u015flevsel de\u011fil, ayn\u0131 zamanda son derece g\u00fcvenli olmas\u0131 \u015fartt\u0131r. Bu makalede, bu dengeyi nas\u0131l kuraca\u011f\u0131m\u0131z\u0131, geli\u015ftirme a\u015famas\u0131ndan ba\u015flay\u0131p uygulaman\u0131z\u0131 \u00fcretime g\u00fcvenle ta\u015f\u0131yacak ad\u0131mlara kadar t\u00fcm s\u00fcreci ayr\u0131nt\u0131l\u0131 bir \u015fekilde ele alaca\u011f\u0131z.<\/p>\n<p>Bu rehber, [Yeni Ba\u015flayan] bir geli\u015ftiricinin bile temelden ba\u015flayarak ad\u0131m ad\u0131m ilerlemesini sa\u011flayacak, ayn\u0131 zamanda [Orta] ve [\u0130leri D\u00fczey] kullan\u0131c\u0131lar i\u00e7in de derinlemesine bilgiler ve en iyi uygulamalar sunacakt\u0131r. Haz\u0131rsan\u0131z, e-posta y\u00f6netimini komut sat\u0131r\u0131n\u0131n g\u00fcc\u00fcyle birle\u015ftirece\u011fimiz bu heyecan verici yolculu\u011fa ba\u015flayal\u0131m!<\/p>\n<\/section>\n<section>\n<h2>Gmail API, OAuth 2.0 ve G\u00fcvenli Eri\u015fim: Temel Kavramlar Nelerdir?<\/h2>\n<p>G\u00fcvenli bir Gmail CLI uygulamas\u0131n\u0131n temelini anlamak i\u00e7in \u00f6ncelikle Gmail API&#8217;nin, OAuth 2.0 protokol\u00fcn\u00fcn ve bunlarla ili\u015fkili g\u00fcvenlik mekanizmalar\u0131n\u0131n nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 kavramam\u0131z gerekiyor. Bu kavramlar, uygulamam\u0131z\u0131n yaln\u0131zca i\u015flevsel olmas\u0131n\u0131 de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131 verilerini korumas\u0131n\u0131 da sa\u011flayacak anahtar bile\u015fenlerdir.<\/p>\n<h3>Gmail API Nedir ve Bize Neler Sunar?<\/h3>\n<p>Gmail API, geli\u015ftiricilerin Google Hesab\u0131 olan herhangi bir kullan\u0131c\u0131n\u0131n Gmail verilerine programatik olarak eri\u015fmesini sa\u011flayan bir RESTful API&#8217;dir. Bu API sayesinde e-postalar\u0131 okuyabilir, g\u00f6nderebilir, silebilir, etiketleyebilir, taslaklar olu\u015fturabilir ve hatta Gmail kutusunu y\u00f6netebilirsiniz. K\u0131sacas\u0131, bir kullan\u0131c\u0131n\u0131n web taray\u0131c\u0131s\u0131 \u00fczerinden Gmail&#8217;de yapabildi\u011fi hemen hemen her \u015feyi kod arac\u0131l\u0131\u011f\u0131yla ger\u00e7ekle\u015ftirebilirsiniz. Ancak bu g\u00fcc\u00fcn, do\u011fru yetkilendirme mekanizmalar\u0131yla kullan\u0131lmas\u0131 hayati \u00f6neme sahiptir.<\/p>\n<p>Gmail API&#8217;si, belirli kaynaklara (kullan\u0131c\u0131n\u0131n e-postalar\u0131, taslaklar\u0131, etiketleri vb.) eri\u015fim sa\u011flamak i\u00e7in HTTP metotlar\u0131 (GET, POST, PUT, DELETE) kullan\u0131r ve verileri genellikle JSON format\u0131nda d\u00f6ner. Bu sayede farkl\u0131 programlama dilleri ve platformlar aras\u0131nda kolayca entegrasyon sa\u011flan\u0131r. Uygulamam\u0131z\u0131n temel amac\u0131, bu API&#8217;nin sundu\u011fu yetenekleri komut sat\u0131r\u0131 \u00fczerinden kullan\u0131c\u0131ya sunmakt\u0131r.<\/p>\n<h3>OAuth 2.0: Kimlik Do\u011frulama ve Yetkilendirmenin Omurgas\u0131<\/h3>\n<p>E-posta adresiniz ve \u015fifreniz gibi hassas bilgileri do\u011frudan CLI uygulaman\u0131zla payla\u015fmak istemezsiniz, de\u011fil mi? \u0130\u015fte tam bu noktada OAuth 2.0 devreye girer. OAuth 2.0, bir uygulamaya (bizim CLI&#8217;m\u0131z) kullan\u0131c\u0131n\u0131n kaynaklar\u0131na (Gmail verileri) do\u011frudan kullan\u0131c\u0131 ad\u0131 ve \u015fifresini payla\u015fmadan s\u0131n\u0131rl\u0131 eri\u015fim izni veren bir end\u00fcstri standard\u0131 yetkilendirme \u00e7er\u00e7evesidir.<\/p>\n<p>Basit\u00e7e ifade etmek gerekirse, CLI uygulamam\u0131z Google&#8217;dan sizin ad\u0131n\u0131za Gmail verilerinize eri\u015fmek i\u00e7in bir &#8220;izin belgesi&#8221; (access token) ister. Siz de Google&#8217;\u0131n g\u00fcvenli web aray\u00fcz\u00fc \u00fczerinden bu izni onaylars\u0131n\u0131z. Bu s\u00fcrecin ak\u0131\u015f\u0131 genellikle \u015f\u00f6yledir:<\/p>\n<ol>\n<li><strong>Uygulama Kimli\u011fi (Client ID) ve Gizli Anahtar (Client Secret):<\/strong> \u0130lk olarak Google Cloud Console \u00fczerinden uygulaman\u0131z i\u00e7in bir proje olu\u015fturur ve OAuth 2.0 istemci kimli\u011fi al\u0131rs\u0131n\u0131z. Bu, Google&#8217;\u0131n uygulaman\u0131z\u0131 tan\u0131mas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Yetkilendirme \u0130ste\u011fi:<\/strong> CLI uygulamas\u0131, kullan\u0131c\u0131n\u0131n web taray\u0131c\u0131s\u0131n\u0131 a\u00e7arak Google&#8217;a bir yetkilendirme iste\u011fi g\u00f6nderir. Bu istekte, uygulaman\u0131n hangi izinlere (\u00f6rne\u011fin, e-posta g\u00f6nderme izni) ihtiyac\u0131 oldu\u011fu belirtilir (<code>scope<\/code>).<\/li>\n<li><strong>Kullan\u0131c\u0131 Onay\u0131:<\/strong> Kullan\u0131c\u0131, Google&#8217;\u0131n g\u00fcvenli sayfas\u0131nda oturum a\u00e7ar ve CLI uygulamas\u0131n\u0131n istedi\u011fi izinleri onaylar.<\/li>\n<li><strong>Yetkilendirme Kodu:<\/strong> Kullan\u0131c\u0131 onay\u0131 sonras\u0131 Google, CLI uygulaman\u0131z\u0131n y\u00f6nlendirme URI&#8217;sine (<code>redirect_uri<\/code>) bir yetkilendirme kodu g\u00f6nderir.<\/li>\n<li><strong>Eri\u015fim Belirteci (Access Token) \u0130ste\u011fi:<\/strong> CLI uygulamas\u0131, ald\u0131\u011f\u0131 yetkilendirme kodu, Client ID ve Client Secret&#8217;\u0131 kullanarak Google&#8217;dan bir eri\u015fim belirteci ister.<\/li>\n<li><strong>Eri\u015fim Belirteci ve Yenileme Belirteci (Refresh Token):<\/strong> Google, ge\u00e7erli bir eri\u015fim belirteci ve (genellikle) daha uzun \u00f6m\u00fcrl\u00fc bir yenileme belirteci g\u00f6nderir. Eri\u015fim belirteci, Gmail API \u00e7a\u011fr\u0131lar\u0131 yapmak i\u00e7in kullan\u0131l\u0131r ve k\u0131sa \u00f6m\u00fcrl\u00fcd\u00fcr (genellikle 1 saat). Yenileme belirteci ise eri\u015fim belirteci s\u00fcresi doldu\u011funda yeni bir eri\u015fim belirteci almak i\u00e7in kullan\u0131l\u0131r ve \u00e7ok daha uzun \u00f6m\u00fcrl\u00fcd\u00fcr veya s\u00fcresiz olabilir.<\/li>\n<\/ol>\n<p>Bu karma\u015f\u0131k s\u00fcre\u00e7, kullan\u0131c\u0131 bilgilerinin g\u00fcvenli\u011fini sa\u011flamak i\u00e7in hayati \u00f6neme sahiptir. Uygulamam\u0131z hi\u00e7bir zaman do\u011frudan kullan\u0131c\u0131 ad\u0131 ve \u015fifrenizi saklamaz veya kullanmaz. Yaln\u0131zca Google&#8217;\u0131n verdi\u011fi, s\u0131n\u0131rl\u0131 yetkili ve s\u00fcresi k\u0131s\u0131tl\u0131 belirte\u00e7lerle i\u015flem yapar. Yenileme belirteci, eri\u015fim belirteci bitti\u011finde uygulaman\u0131n manuel yeniden kimlik do\u011frulama gerektirmeden \u00e7al\u0131\u015fmaya devam etmesini sa\u011flar. Bu, [Yeni Ba\u015flayan] bir kullan\u0131c\u0131n\u0131n bile g\u00fcvenli bir \u015fekilde entegrasyon yapabilmesi i\u00e7in temel bir ad\u0131md\u0131r.<\/p>\n<div class=\"uzman-ipucu\">\n          Uzman \u0130pucu: Yenileme belirte\u00e7lerini (refresh tokens) ve eri\u015fim belirte\u00e7lerini (access tokens) asla a\u00e7\u0131k metin olarak saklamay\u0131n. Daima g\u00fcvenli depolama mekanizmalar\u0131 (\u00f6rne\u011fin, i\u015fletim sisteminin anahtar deposu, \u015fifrelenmi\u015f dosya sistemleri) kullan\u0131n ve bu belirte\u00e7lere yetkisiz eri\u015fimi engelleyin.\n        <\/div>\n<p>Bu temel kavramlar\u0131 anlad\u0131ktan sonra, bir sonraki ad\u0131mda geli\u015ftirme ortam\u0131m\u0131z\u0131 haz\u0131rlayarak kodlamaya ba\u015flayabiliriz.<\/p>\n<\/section>\n<section>\n<h2>Geli\u015ftirme Ortam\u0131n\u0131 Haz\u0131rlamak: Hangi Ara\u00e7lara \u0130htiyac\u0131m\u0131z Var?<\/h2>\n<p>G\u00fcvenli bir Gmail CLI uygulamas\u0131n\u0131 ba\u015far\u0131yla geli\u015ftirmek i\u00e7in do\u011fru ara\u00e7lara ve birle\u015ftirilmi\u015f bir geli\u015ftirme ortam\u0131na ihtiyac\u0131m\u0131z var. Bu b\u00f6l\u00fcm, [Yeni Ba\u015flayan] ve [Orta] seviyedeki geli\u015ftiriciler i\u00e7in temel kurulum ad\u0131mlar\u0131n\u0131 ve dil se\u00e7imi kararlar\u0131n\u0131 ele alacakt\u0131r. Hedefimiz, projemiz i\u00e7in sa\u011flam ve bak\u0131m\u0131 kolay bir temel olu\u015fturmakt\u0131r.<\/p>\n<h3>Programlama Dili Se\u00e7imi: Python mu, Node.js mi?<\/h3>\n<p>Gmail API ile etkile\u015fim kurmak i\u00e7in bir\u00e7ok programlama dilini kullanabilirsiniz, ancak Python ve Node.js bu t\u00fcr CLI uygulamalar\u0131 i\u00e7in pop\u00fcler ve g\u00fc\u00e7l\u00fc se\u00e7eneklerdir. Her birinin kendine g\u00f6re avantajlar\u0131 vard\u0131r:<\/p>\n<ul>\n<li>\n            <strong>Python:<\/strong><\/p>\n<ul>\n<li><strong>Avantajlar\u0131:<\/strong> Temiz ve okunabilir s\u00f6zdizimi, b\u00fcy\u00fck bir geli\u015ftirici toplulu\u011fu, geni\u015f k\u00fct\u00fcphane ekosistemi (<code>google-api-python-client<\/code> gibi), otomasyon ve veri i\u015fleme g\u00f6revleri i\u00e7in \u00e7ok uygun. \u00d6\u011frenmesi nispeten kolayd\u0131r.<\/li>\n<li><strong>Dezavantajlar\u0131:<\/strong> Baz\u0131 durumlarda Node.js&#8217;e g\u00f6re daha yava\u015f \u00e7al\u0131\u015fabilir (\u00f6zellikle yo\u011fun I\/O i\u015flemlerinde), da\u011f\u0131t\u0131m\u0131 bazen biraz daha karma\u015f\u0131k olabilir (\u00e7al\u0131\u015fma zaman\u0131 ba\u011f\u0131ml\u0131l\u0131klar\u0131).<\/li>\n<\/ul>\n<\/li>\n<li>\n            <strong>Node.js (JavaScript):<\/strong><\/p>\n<ul>\n<li><strong>Avantajlar\u0131:<\/strong> Asenkron yap\u0131s\u0131 sayesinde y\u00fcksek performansl\u0131 I\/O i\u015flemleri i\u00e7in idealdir, tek bir dil (JavaScript) ile hem \u00f6n y\u00fcz hem de arka y\u00fcz geli\u015ftirme imkan\u0131 sunar, <code>npm<\/code> paketi y\u00f6neticisi ile zengin k\u00fct\u00fcphane deste\u011fi (<code>googleapis<\/code> gibi).<\/li>\n<li><strong>Dezavantajlar\u0131:<\/strong> Callback veya Promise zincirleri bazen kodun okunabilirli\u011fini azaltabilir (async\/await ile b\u00fcy\u00fck \u00f6l\u00e7\u00fcde \u00e7\u00f6z\u00fcld\u00fc), Python&#8217;a g\u00f6re ba\u015flang\u0131\u00e7ta \u00f6\u011frenme e\u011frisi biraz daha dik olabilir.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Bu makalede, Python&#8217;\u0131n sadeli\u011fi ve otomasyon senaryolar\u0131ndaki yayg\u0131nl\u0131\u011f\u0131 nedeniyle Python&#8217;\u0131 tercih edece\u011fiz. Ancak anlat\u0131lan prensipler Node.js veya di\u011fer diller i\u00e7in de ge\u00e7erli olacakt\u0131r.<\/p>\n<h3>Python Geli\u015ftirme Ortam\u0131n\u0131 Kurmak<\/h3>\n<p>Python ile \u00e7al\u0131\u015fmak i\u00e7in a\u015fa\u011f\u0131daki ad\u0131mlar\u0131 izleyin:<\/p>\n<ol>\n<li>\n            <strong>Python Kurulumu:<\/strong> Sisteminizde Python 3.8 veya \u00fczeri bir s\u00fcr\u00fcm\u00fcn kurulu oldu\u011fundan emin olun.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-bash\">\n                <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n                python3 --version\n              <\/pre>\n<p><\/code>\n            <\/div>\n<p>E\u011fer kurulu de\u011filse, <a href=\"https:\/\/www.python.org\/downloads\/\" target=\"_blank\">Python resmi web sitesinden<\/a> indirebilirsiniz.<\/p>\n<\/li>\n<li>\n            <strong>Sanal Ortam Olu\u015fturma:<\/strong> Projenizin ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 sistem genelindeki Python paketlerinden izole etmek i\u00e7in sanal bir ortam olu\u015fturmak iyi bir pratiktir.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-bash\">\n                <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n                mkdir gmail-cli\n                cd gmail-cli\n                python3 -m venv venv\n              <\/pre>\n<p><\/code>\n            <\/div>\n<\/li>\n<li>\n            <strong>Sanal Ortam\u0131 Aktifle\u015ftirme:<\/strong><\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-bash\">\n                <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n                # Linux\/macOS\n                source venv\/bin\/activate\n\n                # Windows\n                .\\venv\\Scripts\\activate\n              <\/pre>\n<p><\/code>\n            <\/div>\n<\/li>\n<li>\n            <strong>Gerekli K\u00fct\u00fcphaneleri Y\u00fckleme:<\/strong> Gmail API ile etkile\u015fim kurmak i\u00e7in Google'\u0131n resmi Python istemci k\u00fct\u00fcphanesine ihtiyac\u0131m\u0131z olacak. Ayr\u0131ca, OAuth kimlik do\u011frulama s\u00fcrecini kolayla\u015ft\u0131ran k\u00fct\u00fcphaneler de gereklidir.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-bash\">\n                <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n                pip install google-api-python-client google-auth-oauthlib google-auth-httplib2\n              <\/pre>\n<p><\/code>\n            <\/div>\n<ul>\n<li><code>google-api-python-client<\/code>: Google API'leri ile konu\u015fmak i\u00e7in ana k\u00fct\u00fcphane.<\/li>\n<li><code>google-auth-oauthlib<\/code>: OAuth 2.0 kimlik do\u011frulama ak\u0131\u015f\u0131n\u0131 kolayla\u015ft\u0131r\u0131r.<\/li>\n<li><code>google-auth-httplib2<\/code>: HTTP isteklerini Google Auth ile entegre eder.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<h3>Google Cloud Console'da Proje Olu\u015fturma ve API Etkinle\u015ftirme<\/h3>\n<p>Uygulaman\u0131z\u0131n Gmail API'ye eri\u015febilmesi i\u00e7in Google Cloud Console'da bir proje olu\u015fturman\u0131z ve ilgili API'yi etkinle\u015ftirmeniz gerekir:<\/p>\n<ol>\n<li><a href=\"https:\/\/console.cloud.google.com\/\" target=\"_blank\">Google Cloud Console'a<\/a> gidin ve yeni bir proje olu\u015fturun.<\/li>\n<li>Projenizi se\u00e7tikten sonra, sol men\u00fcden \"APIs & Services\" > \"Dashboard\"a gidin.<\/li>\n<li>\"+ ENABLE APIS AND SERVICES\" butonuna t\u0131klay\u0131n ve \"Gmail API\"yi aratarak etkinle\u015ftirin.<\/li>\n<li>Yine \"APIs & Services\" alt\u0131nda \"Credentials\" b\u00f6l\u00fcm\u00fcne gidin.<\/li>\n<li>\"CREATE CREDENTIALS\" butonuna t\u0131klay\u0131n ve \"OAuth client ID\" se\u00e7ene\u011fini se\u00e7in.<\/li>\n<li>Uygulama t\u00fcr\u00fc olarak \"Desktop app\" (masa\u00fcst\u00fc uygulamas\u0131) se\u00e7ene\u011fini i\u015faretleyin. CLI uygulamalar\u0131 genellikle bu kategoride de\u011ferlendirilir \u00e7\u00fcnk\u00fc taray\u0131c\u0131 tabanl\u0131 y\u00f6nlendirme kullan\u0131rlar. Bir isim verin ve olu\u015fturun.<\/li>\n<li>Olu\u015fturulduktan sonra, \"Client ID\" ve \"Client Secret\" bilgilerini i\u00e7eren bir JSON dosyas\u0131 indirebilirsiniz. Bu dosyay\u0131 projenizin k\u00f6k dizinine <code>credentials.json<\/code> ad\u0131yla kaydedin. <strong>Bu dosya hassas bilgiler i\u00e7erdi\u011fi i\u00e7in asla genel bir depoya (\u00f6rne\u011fin GitHub'a) y\u00fcklemeyin!<\/strong><\/li>\n<\/ol>\n<div class=\"guvenlik-uyarisi\">\n<h4>Dikkat: Hassas Veri Y\u00f6netimi!<\/h4>\n<p><code>credentials.json<\/code> dosyas\u0131, uygulaman\u0131z\u0131n Google API'lerine eri\u015fimini sa\u011flayan anahtarlar\u0131 i\u00e7erir. Bu dosyay\u0131 kesinlikle kaynak kontrol sistemlerinize (Git) dahil etmeyin. Bunun yerine <code>.gitignore<\/code> dosyas\u0131na ekleyin ve g\u00fcvenli bir \u015fekilde saklay\u0131n. \u00dcretim ortam\u0131nda bu kimlik bilgilerinin \u00e7evre de\u011fi\u015fkenleri veya g\u00fcvenli anahtar y\u00f6netimi servisleri arac\u0131l\u0131\u011f\u0131yla sa\u011flanmas\u0131 esast\u0131r.<\/p>\n<\/p><\/div>\n<p>Bu ad\u0131mlarla birlikte geli\u015ftirme ortam\u0131m\u0131z haz\u0131r hale geldi. Art\u0131k Gmail API ile etkile\u015fim kurmaya ba\u015flayabiliriz. Bu kurulum, [Orta] seviye bir geli\u015ftiricinin bile kolayca uygulamas\u0131n\u0131 sa\u011flayacak detaydad\u0131r.<\/p>\n<\/section>\n<section>\n<h2>Uygulamal\u0131 K\u0131s\u0131m: \u0130lk G\u00fcvenli Gmail CLI Komutlar\u0131n\u0131 Nas\u0131l Yazar\u0131z?<\/h2>\n<p>Geli\u015ftirme ortam\u0131m\u0131z haz\u0131r oldu\u011funa g\u00f6re, art\u0131k kod yazmaya ba\u015flayabiliriz. Bu b\u00f6l\u00fcmde, OAuth kimlik do\u011frulama ak\u0131\u015f\u0131n\u0131 uygulayacak ve basit Gmail CLI komutlar\u0131 olu\u015fturaca\u011f\u0131z. Bu k\u0131s\u0131m, [Orta] d\u00fczeydeki geli\u015ftiriciler i\u00e7in temel bir ba\u015flang\u0131\u00e7 noktas\u0131 sunarken, [Yeni Ba\u015flayan] kullan\u0131c\u0131lar\u0131n da ad\u0131m ad\u0131m ilerlemesini sa\u011flayacakt\u0131r.<\/p>\n<h3>OAuth Kimlik Do\u011frulama Ak\u0131\u015f\u0131n\u0131 Uygulama<\/h3>\n<p>Daha \u00f6nce bahsetti\u011fimiz OAuth 2.0 ak\u0131\u015f\u0131n\u0131 Python koduyla nas\u0131l ger\u00e7ekle\u015ftirece\u011fimizi g\u00f6relim. Amac\u0131m\u0131z, uygulaman\u0131n ilk kez \u00e7al\u0131\u015ft\u0131\u011f\u0131nda kullan\u0131c\u0131dan kimlik do\u011frulamas\u0131n\u0131 istemesi, ard\u0131ndan eri\u015fim ve yenileme belirte\u00e7lerini g\u00fcvenli bir \u015fekilde kaydetmesidir. Sonraki \u00e7al\u0131\u015ft\u0131rmalarda ise bu belirte\u00e7leri kullanarak do\u011frudan Gmail API'ye eri\u015fim sa\u011flamas\u0131d\u0131r.<\/p>\n<p>Proje dizininizde <code>gmail_cli.py<\/code> ad\u0131nda bir dosya olu\u015fturun ve a\u015fa\u011f\u0131daki kodla ba\u015flay\u0131n:<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-python\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            import os\n            import os.path\n            import pickle\n\n            from google_auth_oauthlib.flow import InstalledAppFlow\n            from google.auth.transport.requests import Request\n            from googleapiclient.discovery import build\n\n            # Gmail API'nin ihtiya\u00e7 duydu\u011fu SCOPE'lar (izinler)\n            # Daha fazla SCOPE i\u00e7in Google'\u0131n dok\u00fcmantasyonunu inceleyebilirsiniz:\n            # https:\/\/developers.google.com\/gmail\/api\/auth\/scopes\n            SCOPES = ['https:\/\/www.googleapis.com\/auth\/gmail.readonly', 'https:\/\/www.googleapis.com\/auth\/gmail.send']\n\n            def get_gmail_service():\n                \"\"\"\n                Gmail API servisini olu\u015fturur ve d\u00f6nd\u00fcr\u00fcr.\n                Eri\u015fim belirte\u00e7leri (tokens) varsa kullan\u0131r, yoksa kimlik do\u011frulama ak\u0131\u015f\u0131n\u0131 ba\u015flat\u0131r.\n                \"\"\"\n                creds = None\n                # Token dosyas\u0131n\u0131 kontrol et (daha \u00f6nce kimlik do\u011frulama yap\u0131lm\u0131\u015fsa)\n                if os.path.exists('token.pickle'):\n                    with open('token.pickle', 'rb') as token:\n                        creds = pickle.load(token)\n\n                # Ge\u00e7erli token yoksa veya s\u00fcresi dolmu\u015fsa\n                if not creds or not creds.valid:\n                    if creds and creds.expired and creds.refresh_token:\n                        # Token s\u00fcresi dolmu\u015f ama refresh token varsa yenile\n                        try:\n                            creds.refresh(Request())\n                        except Exception as e:\n                            print(f\"Token yenileme hatas\u0131: {e}. Yeniden kimlik do\u011frulan\u0131yor.\")\n                            creds = None # Hata durumunda yeniden kimlik do\u011frulama i\u00e7in creds'i s\u0131f\u0131rla\n                    else:\n                        # Yeni kimlik do\u011frulama ak\u0131\u015f\u0131 ba\u015flat\n                        flow = InstalledAppFlow.from_client_secrets_file(\n                            'credentials.json', SCOPES)\n                        creds = flow.run_local_server(port=0)\n\n                    # Yeni token'\u0131 kaydet\n                    with open('token.pickle', 'wb') as token:\n                        pickle.dump(creds, token)\n\n                return build('gmail', 'v1', credentials=creds)\n\n            if __name__ == '__main__':\n                print(\"Gmail CLI uygulamas\u0131na ho\u015f geldiniz!\")\n                try:\n                    service = get_gmail_service()\n                    print(\"Gmail API servisi ba\u015far\u0131yla olu\u015fturuldu.\")\n                    # Burada di\u011fer CLI komutlar\u0131n\u0131z\u0131 \u00e7a\u011f\u0131rabilirsiniz\n                except Exception as e:\n                    print(f\"Bir hata olu\u015ftu: {e}\")\n\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p>Bu kod blo\u011fu, <code>token.pickle<\/code> ad\u0131nda bir dosya kullanarak eri\u015fim belirte\u00e7lerini y\u00f6netir. E\u011fer dosya yoksa veya belirte\u00e7ler ge\u00e7ersizse, Google Cloud Console'dan indirdi\u011finiz <code>credentials.json<\/code> dosyas\u0131n\u0131 kullanarak bir web taray\u0131c\u0131s\u0131 a\u00e7ar ve kullan\u0131c\u0131dan izin ister. Ba\u015far\u0131l\u0131 bir kimlik do\u011frulamadan sonra belirte\u00e7ler <code>token.pickle<\/code> dosyas\u0131na kaydedilir.<\/p>\n<div class=\"guvenlik-uyarisi\">\n<h4>Dikkat: pickle ile Token Kaydetme<\/h4>\n<p><code>pickle<\/code> mod\u00fcl\u00fc, Python objelerini serile\u015ftirmek i\u00e7in kullan\u0131l\u0131r ancak g\u00fcvenlik riskleri ta\u015f\u0131yabilir (g\u00fcvenilmeyen kaynaklardan y\u00fcklenen pickle dosyalar\u0131 kod \u00e7al\u0131\u015ft\u0131rmaya neden olabilir). Daha g\u00fcvenli bir y\u00f6ntem olarak belirte\u00e7leri \u015fifrelenmi\u015f bir dosyaya veya i\u015fletim sisteminin anahtar deposuna (keyring) kaydetmek \u00f6nerilir. Ancak bu \u00f6rnek i\u00e7in basitlik ad\u0131na <code>pickle<\/code> kullan\u0131lm\u0131\u015ft\u0131r. \u00dcretim ortamlar\u0131nda daha sa\u011flam \u00e7\u00f6z\u00fcmler d\u00fc\u015f\u00fcn\u00fclmelidir.<\/p>\n<\/p><\/div>\n<h3>E-posta Listeleme Komutu Nas\u0131l Yaz\u0131l\u0131r?<\/h3>\n<p>\u015eimdi Gmail API servisimizi kullanarak basit bir e-posta listeleme i\u015flevi ekleyelim. Bu, kullan\u0131c\u0131n\u0131n gelen kutusundaki en son e-postalar\u0131 g\u00f6stermeyi ama\u00e7lar.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-python\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            # ... (\u00f6nceki kod) ...\n\n            def list_messages(service, user_id='me', label_ids=['INBOX'], max_results=10):\n                \"\"\"\n                Belirtilen etiketlere sahip e-postalar\u0131 listeler.\n                \"\"\"\n                try:\n                    results = service.users().messages().list(userId=user_id, labelIds=label_ids,\n                                                              maxResults=max_results).execute()\n                    messages = results.get('messages', [])\n\n                    if not messages:\n                        print('Gelen kutusunda e-posta bulunamad\u0131.')\n                        return\n\n                    print(f\"\\nSon {len(messages)} e-posta:\")\n                    for message in messages:\n                        msg = service.users().messages().get(userId=user_id, id=message['id'], format='metadata',\n                                                             metadataHeaders=['From', 'Subject', 'Date']).execute()\n                        headers = msg['payload']['headers']\n                        msg_from = next((h['value'] for h in headers if h['name'] == 'From'), 'Bilinmeyen G\u00f6nderen')\n                        msg_subject = next((h['value'] for h in headers if h['name'] == 'Subject'), 'Konu Yok')\n                        msg_date = next((h['value'] for h in headers if h['name'] == 'Date'), 'Bilinmeyen Tarih')\n                        print(f\"- G\u00f6nderen: {msg_from}, Konu: {msg_subject}, Tarih: {msg_date}\")\n\n                except Exception as e:\n                    print(f\"E-postalar listelenirken bir hata olu\u015ftu: {e}\")\n\n            if __name__ == '__main__':\n                print(\"Gmail CLI uygulamas\u0131na ho\u015f geldiniz!\")\n                try:\n                    service = get_gmail_service()\n                    print(\"Gmail API servisi ba\u015far\u0131yla olu\u015fturuldu.\")\n                    list_messages(service) # Art\u0131k e-postalar\u0131 listeleyebiliriz\n                except Exception as e:\n                    print(f\"Uygulama ba\u015flat\u0131l\u0131rken bir hata olu\u015ftu: {e}\")\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p>Bu <code>list_messages<\/code> fonksiyonu, varsay\u0131lan olarak gelen kutusundaki son 10 e-postay\u0131 listeler. Her e-postan\u0131n g\u00f6nderenini, konusunu ve tarihini getirir. API'den sadece bu ba\u015fl\u0131k bilgilerini isteyerek (<code>format='metadata', metadataHeaders<\/code>) performans\u0131 art\u0131r\u0131r\u0131z, \u00e7\u00fcnk\u00fc t\u00fcm e-posta i\u00e7eri\u011fini indirmeye gerek kalmaz.<\/p>\n<h3>E-posta G\u00f6nderme Komutu Nas\u0131l Olu\u015fturulur?<\/h3>\n<p>E-posta listeleme kadar e-posta g\u00f6nderme de \u00f6nemli bir fonksiyondur. Bunun i\u00e7in MIME format\u0131nda bir e-posta olu\u015fturup Gmail API arac\u0131l\u0131\u011f\u0131yla g\u00f6nderece\u011fiz.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-python\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            # ... (\u00f6nceki kodlar) ...\n            from email.mime.text import MIMEText\n            import base64\n\n            # ... (get_gmail_service ve list_messages fonksiyonlar\u0131) ...\n\n            def create_message(sender, to, subject, message_text):\n                \"\"\"MIME format\u0131nda bir e-posta mesaj\u0131 olu\u015fturur.\"\"\"\n                message = MIMEText(message_text)\n                message['to'] = to\n                message['from'] = sender\n                message['subject'] = subject\n                return {'raw': base64.urlsafe_b64encode(message.as_bytes()).decode()}\n\n            def send_message(service, user_id, message):\n                \"\"\"Olu\u015fturulan e-posta mesaj\u0131n\u0131 g\u00f6nderir.\"\"\"\n                try:\n                    sent_message = service.users().messages().send(userId=user_id, body=message).execute()\n                    print(f\"E-posta ba\u015far\u0131yla g\u00f6nderildi! Mesaj Kimli\u011fi: {sent_message['id']}\")\n                    return sent_message\n                except Exception as e:\n                    print(f\"E-posta g\u00f6nderilirken bir hata olu\u015ftu: {e}\")\n                    return None\n\n            if __name__ == '__main__':\n                print(\"Gmail CLI uygulamas\u0131na ho\u015f geldiniz!\")\n                try:\n                    service = get_gmail_service()\n                    print(\"Gmail API servisi ba\u015far\u0131yla olu\u015fturuldu.\")\n\n                    # E-postalar\u0131 listele\n                    list_messages(service)\n\n                    # \u00d6rnek bir e-posta g\u00f6nderimi (kendi e-posta adresinizi kullan\u0131n)\n                    # sender = \"sizin_email_adresiniz@gmail.com\" # Buray\u0131 kendi adresinizle g\u00fcncelleyin\n                    # to = \"hedef_email_adresiniz@example.com\"\n                    # subject = \"CLI Uygulamas\u0131ndan Test E-postas\u0131\"\n                    # message_text = \"Bu, Python CLI uygulamamdan g\u00f6nderilen bir test e-postas\u0131d\u0131r.\"\n                    #\n                    # message = create_message(sender, to, subject, message_text)\n                    # send_message(service, 'me', message)\n\n                except Exception as e:\n                    print(f\"Uygulama ba\u015flat\u0131l\u0131rken bir hata olu\u015ftu: {e}\")\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p><code>create_message<\/code> fonksiyonu, Python'\u0131n <code>email.mime.text<\/code> mod\u00fcl\u00fcn\u00fc kullanarak basit bir metin e-postas\u0131 olu\u015fturur ve bunu base64 ile \u015fifreler. <code>send_message<\/code> fonksiyonu ise bu mesaj\u0131 Gmail API arac\u0131l\u0131\u011f\u0131yla g\u00f6nderir. G\u00f6nderme i\u015flemi i\u00e7in <code>https:\/\/www.googleapis.com\/auth\/gmail.send<\/code> iznine sahip olman\u0131z gerekti\u011fini unutmay\u0131n, bu izni SCOPES listemize ekledik.<\/p>\n<p>Bu ad\u0131mlar, [Orta] seviye bir kullan\u0131c\u0131 i\u00e7in hem kimlik do\u011frulaman\u0131n hem de temel API etkile\u015fimlerinin nas\u0131l yap\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6sterir. Art\u0131k uygulaman\u0131z\u0131 \u00e7al\u0131\u015ft\u0131rabilir, kimlik do\u011frulamas\u0131 yapabilir ve ilk e-postalar\u0131n\u0131z\u0131 listeleyip g\u00f6nderebilirsiniz. Uygulaman\u0131z\u0131n temel iskeleti olu\u015ftu. Bir sonraki ad\u0131mda, bu temel yap\u0131n\u0131n g\u00fcvenlik katmanlar\u0131n\u0131 daha derinlemesine inceleyece\u011fiz.<\/p>\n<\/section>\n<section>\n<h2>G\u00fcvenlik Katmanlar\u0131n\u0131 Derinlemesine \u0130ncelemek: Verilerinizi Nas\u0131l Korursunuz?<\/h2>\n<p>Bir Gmail CLI uygulamas\u0131 geli\u015ftirirken i\u015flevsellik kadar, hatta belki ondan daha fazla \u00f6nem ta\u015f\u0131yan bir konu da g\u00fcvenliktir. Kullan\u0131c\u0131lar\u0131n hassas e-posta verilerine eri\u015fim sa\u011fl\u0131yorsak, bu verilere yetkisiz eri\u015fimi engellemek ve gizlili\u011fi sa\u011flamak zorunday\u0131z. Bu b\u00f6l\u00fcm, [Orta] seviyeden [\u0130leri D\u00fczey] seviyeye kadar, g\u00fcvenlik katmanlar\u0131n\u0131 nas\u0131l g\u00fc\u00e7lendirebilece\u011fimizi ayr\u0131nt\u0131lar\u0131yla ele alacakt\u0131r.<\/p>\n<h3>Token Y\u00f6netimi: Nerede ve Nas\u0131l Saklamal\u0131y\u0131z?<\/h3>\n<p>\u00d6nceki b\u00f6l\u00fcmde, basitlik ad\u0131na belirte\u00e7leri (access ve refresh token'lar) <code>token.pickle<\/code> dosyas\u0131na kaydettik. Ancak \u00fcretim ortamlar\u0131nda bu y\u00f6ntem yetersiz kal\u0131r ve ciddi g\u00fcvenlik a\u00e7\u0131klar\u0131 yaratabilir. G\u00fcvenli token y\u00f6netimi i\u00e7in a\u015fa\u011f\u0131daki yakla\u015f\u0131mlar \u00f6nerilir:<\/p>\n<ol>\n<li>\n            <strong>\u0130\u015fletim Sistemi Anahtar Deposu (Keyring):<\/strong><\/p>\n<p>\u00c7o\u011fu i\u015fletim sistemi (Windows'ta Credential Manager, macOS'ta Keychain, Linux'ta GNOME Keyring\/KWallet) hassas verileri g\u00fcvenli bir \u015fekilde saklamak i\u00e7in yerle\u015fik mekanizmalara sahiptir. Python i\u00e7in <code>keyring<\/code> k\u00fct\u00fcphanesi bu sistemlerle entegrasyonu sa\u011flar. Bu, kullan\u0131c\u0131 ba\u015f\u0131na belirte\u00e7leri g\u00fcvenli bir \u015fekilde saklaman\u0131n en iyi yollar\u0131ndan biridir, \u00e7\u00fcnk\u00fc veriler kullan\u0131c\u0131n\u0131n oturum a\u00e7t\u0131\u011f\u0131 kullan\u0131c\u0131 hesab\u0131 alt\u0131nda \u015fifrelenir ve korunur.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-bash\">\n                <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n                pip install keyring\n              <\/pre>\n<p><\/code>\n            <\/div>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-python\">\n                <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n                import keyring\n                import json\n\n                SERVICE_ID = \"GmailCliApp\" # Uygulaman\u0131z i\u00e7in benzersiz bir kimlik\n\n                def save_tokens_securely(creds):\n                    \"\"\"Tokens'\u0131 keyring'e kaydeder.\"\"\"\n                    token_data = {\n                        'token': creds.token,\n                        'refresh_token': creds.refresh_token,\n                        'token_uri': creds.token_uri,\n                        'client_id': creds.client_id,\n                        'client_secret': creds.client_secret,\n                        'scopes': creds.scopes\n                    }\n                    keyring.set_password(SERVICE_ID, \"gmail_cli_user\", json.dumps(token_data))\n                    print(\"Token'lar g\u00fcvenli bir \u015fekilde kaydedildi.\")\n\n                def load_tokens_securely():\n                    \"\"\"Keyring'den token'lar\u0131 y\u00fckler.\"\"\"\n                    stored_data = keyring.get_password(SERVICE_ID, \"gmail_cli_user\")\n                    if stored_data:\n                        try:\n                            token_data = json.loads(stored_data)\n                            from google.oauth2.credentials import Credentials\n                            creds = Credentials(\n                                token=token_data['token'],\n                                refresh_token=token_data.get('refresh_token'),\n                                token_uri=token_data['token_uri'],\n                                client_id=token_data['client_id'],\n                                client_secret=token_data['client_secret'],\n                                scopes=token_data['scopes']\n                            )\n                            return creds\n                        except json.JSONDecodeError:\n                            print(\"Keyring'deki token verileri bozuk.\")\n                            return None\n                    return None\n\n                # get_gmail_service fonksiyonunda bu metodlar\u0131 kullanabilirsiniz\n                # if os.path.exists('token.pickle'): yerine\n                # creds = load_tokens_securely()\n                # ve pickle.dump yerine save_tokens_securely(creds)\n              <\/pre>\n<p><\/code>\n            <\/div>\n<\/li>\n<li>\n            <strong>Ortam De\u011fi\u015fkenleri:<\/strong> \u00d6zellikle sunucu ortamlar\u0131nda veya Docker konteynerlerinde Client ID ve Client Secret gibi kritik bilgileri do\u011frudan dosyalarda saklamak yerine ortam de\u011fi\u015fkenleri olarak sa\u011flamak daha g\u00fcvenlidir. Bu, kimlik bilgilerinin dosya sisteminde kal\u0131c\u0131 olmas\u0131n\u0131 engeller.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-bash\">\n                <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n                export GOOGLE_CLIENT_ID=\"your_client_id_from_console\"\n                export GOOGLE_CLIENT_SECRET=\"your_client_secret_from_console\"\n              <\/pre>\n<p><\/code>\n            <\/div>\n<p>Uygulaman\u0131zda bunlar\u0131 <code>os.environ.get('GOOGLE_CLIENT_ID')<\/code> ile okuyabilirsiniz.<\/p>\n<\/li>\n<li>\n            <strong>Bulut Tabanl\u0131 Anahtar Y\u00f6netimi:<\/strong> AWS Secrets Manager, Google Secret Manager veya Azure Key Vault gibi servisler, hassas bilgileri merkezi ve g\u00fcvenli bir \u015fekilde y\u00f6netmek i\u00e7in tasarlanm\u0131\u015ft\u0131r. Bu servisler, \u00fcretim ortamlar\u0131nda token ve anahtar y\u00f6netimini \u00f6l\u00e7eklenebilir ve g\u00fcvenli hale getirir. Bu [\u0130leri D\u00fczey] bir \u00e7\u00f6z\u00fcmd\u00fcr.\n          <\/li>\n<\/ol>\n<h3>Yetkilendirme Kapsam\u0131 (Scopes) ve En Az Ayr\u0131cal\u0131k Prensibi<\/h3>\n<p>Gmail API'sine eri\u015fim isterken, uygulaman\u0131z\u0131n hangi verilere ve hangi i\u015flemlere yetkisi olaca\u011f\u0131n\u0131 belirleyen \"scope\"lar kullan\u0131r\u0131z. \u00d6rne\u011fin:<\/p>\n<ul>\n<li><code>https:\/\/www.googleapis.com\/auth\/gmail.readonly<\/code>: Sadece e-postalar\u0131 okuma izni.<\/li>\n<li><code>https:\/\/www.googleapis.com\/auth\/gmail.send<\/code>: Sadece e-posta g\u00f6nderme izni.<\/li>\n<li><code>https:\/\/www.googleapis.com\/auth\/gmail.modify<\/code>: E-postalar\u0131 okuma, yazma, silme, etiketleme izni.<\/li>\n<li><code>https:\/\/www.googleapis.com\/auth\/gmail.compose<\/code>: E-posta tasla\u011f\u0131 olu\u015fturma ve g\u00f6nderme izni.<\/li>\n<li><code>https:\/\/www.googleapis.com\/auth\/gmail.full<\/code>: Tam eri\u015fim.<\/li>\n<\/ul>\n<div class=\"guvenlik-uyarisi\">\n<h4>Dikkat: En Az Ayr\u0131cal\u0131k Prensibi!<\/h4>\n<p>Uygulaman\u0131z\u0131n ger\u00e7ekten ihtiyac\u0131 olan en dar kapsaml\u0131 izinleri isteyin. \u00d6rne\u011fin, uygulaman\u0131z yaln\u0131zca e-posta g\u00f6nderecekse, <code>gmail.send<\/code> kapsam\u0131n\u0131 kullan\u0131n, <code>gmail.full<\/code> de\u011fil. Bu, bir g\u00fcvenlik ihlali durumunda potansiyel zarar\u0131 minimize eder. Bu, g\u00fcvenlik d\u00fcnyas\u0131nda \"En Az Ayr\u0131cal\u0131k Prensibi\" (Principle of Least Privilege) olarak bilinir.<\/p>\n<\/p><\/div>\n<h3>Hata \u0130\u015fleme ve G\u00fcnl\u00fck Kayd\u0131 (Logging)<\/h3>\n<p>G\u00fcvenli bir uygulaman\u0131n sa\u011flam bir hata i\u015fleme ve g\u00fcnl\u00fck kayd\u0131 mekanizmas\u0131na sahip olmas\u0131 gerekir. G\u00fcvenlik olaylar\u0131, API hatalar\u0131 veya yetkisiz eri\u015fim denemeleri gibi durumlar do\u011fru bir \u015fekilde kaydedilmelidir. Ancak, g\u00fcnl\u00fck kaydederken hassas bilgilerin (\u00f6rne\u011fin tam API yan\u0131tlar\u0131, token'lar) log dosyalar\u0131na s\u0131zmamas\u0131na dikkat edin.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-python\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            import logging\n\n            logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')\n\n            # ... (get_gmail_service i\u00e7inde hata yakalama) ...\n            try:\n                creds.refresh(Request())\n            except Exception as e:\n                logging.error(f\"Token yenileme hatas\u0131: {e}. Yeniden kimlik do\u011frulan\u0131yor.\")\n                creds = None # Hata durumunda yeniden kimlik do\u011frulama i\u00e7in creds'i s\u0131f\u0131rla\n\n            # ... (list_messages i\u00e7inde hata yakalama) ...\n            except Exception as e:\n                logging.error(f\"E-postalar listelenirken bir hata olu\u015ftu: {e}\")\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p>Bu, [Orta] seviye bir kullan\u0131c\u0131 i\u00e7in loglamay\u0131 ba\u015flatman\u0131n basit bir yoludur. Daha [\u0130leri D\u00fczey] senaryolarda, loglar\u0131 merkezi bir log y\u00f6netimi sistemine (ELK Stack, Splunk, Graylog) g\u00f6ndermek ve anomali tespiti i\u00e7in kullanmak faydal\u0131 olabilir.<\/p>\n<h3>Veri \u015eifreleme ve Aktar\u0131m G\u00fcvenli\u011fi<\/h3>\n<p>Gmail API'si ile t\u00fcm ileti\u015fim HTTPS \u00fczerinden ger\u00e7ekle\u015fir, bu da aktar\u0131m halindeki verilerin \u015fifrelendi\u011fi anlam\u0131na gelir. Ancak, uygulaman\u0131z\u0131n i\u00e7inde yerel olarak depolanan hassas veriler (\u00f6rne\u011fin ge\u00e7ici dosyalar, loglar) i\u00e7in de \u015fifreleme d\u00fc\u015f\u00fcnmelisiniz. E\u011fer token'lar\u0131 keyring yerine bir dosyaya kaydetmeniz gerekiyorsa, bu dosyan\u0131n dosya sistemi d\u00fczeyinde \u015fifrelendi\u011finden emin olun (\u00f6rn. BitLocker, VeraCrypt).<\/p>\n<p>T\u00fcm bu g\u00fcvenlik katmanlar\u0131n\u0131 do\u011fru bir \u015fekilde uygulamak, hem uygulaman\u0131z\u0131n g\u00fcvenli\u011fini art\u0131racak hem de kullan\u0131c\u0131lar\u0131n\u0131z\u0131n verilerine duyulan g\u00fcveni peki\u015ftirecektir. Unutmay\u0131n, g\u00fcvenlik s\u00fcrekli bir s\u00fcre\u00e7tir ve d\u00fczenli olarak g\u00f6zden ge\u00e7irilmelidir.<\/p>\n<\/section>\n<section>\n<h2>Performans ve Optimizasyon: CLI Uygulaman\u0131z\u0131 Daha Verimli Hale Nas\u0131l Getirirsiniz?<\/h2>\n<p>G\u00fcvenlik kadar, CLI uygulamalar\u0131n\u0131z\u0131n performans\u0131 da kullan\u0131c\u0131 deneyimi ve kaynak verimlili\u011fi a\u00e7\u0131s\u0131ndan kritik \u00f6neme sahiptir. \u00d6zellikle Gmail API gibi harici servislerle etkile\u015fimde bulunurken, API kotalar\u0131, gecikme s\u00fcreleri ve veri transferi gibi fakt\u00f6rleri g\u00f6z \u00f6n\u00fcnde bulundurarak uygulaman\u0131z\u0131 optimize etmeniz gerekir. Bu b\u00f6l\u00fcm, [\u0130leri D\u00fczey] geli\u015ftiricilere y\u00f6nelik ipu\u00e7lar\u0131 ve teknikler sunacakt\u0131r.<\/p>\n<h3>API Kotalar\u0131 ve Oran S\u0131n\u0131rlamalar\u0131 (Rate Limiting)<\/h3>\n<p>Google API'leri genellikle belirli kullan\u0131m kotalar\u0131na sahiptir. \u00d6rne\u011fin, Gmail API'sinde belirli bir zaman diliminde yapabilece\u011finiz sorgu say\u0131s\u0131na bir s\u0131n\u0131rland\u0131rma (rate limit) getirilebilir. Bu kotalar\u0131 a\u015fmak, uygulaman\u0131z\u0131n ge\u00e7ici olarak engellenmesine yol a\u00e7abilir.<\/p>\n<div class=\"uzman-ipucu\">\n          Uzman \u0130pucu: Google Cloud Console'da \"APIs & Services\" -> \"Dashboard\" alt\u0131ndan projenizin API kotalar\u0131n\u0131 takip edebilirsiniz. Kota a\u015f\u0131mlar\u0131n\u0131 engellemek i\u00e7in kodunuzda \"Exponential Backoff\" (\u00dcstel Geri \u00c7ekilme) stratejisi uygulay\u0131n. Bu strateji, API iste\u011fi ba\u015far\u0131s\u0131z oldu\u011funda belirli bir s\u00fcre bekleyip tekrar denemeyi i\u00e7erir ve her denemede bekleme s\u00fcresini art\u0131r\u0131r.\n        <\/div>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-python\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            import time\n            import random\n            from googleapiclient.errors import HttpError\n\n            def make_api_call_with_retry(service_method, *args, **kwargs):\n                \"\"\"\n                API \u00e7a\u011fr\u0131lar\u0131n\u0131 \u00fcssel geri \u00e7ekilme ile tekrar denemeyi sa\u011flar.\n                \"\"\"\n                max_retries = 5\n                for i in range(max_retries):\n                    try:\n                        return service_method(*args, **kwargs).execute()\n                    except HttpError as e:\n                        if e.resp.status in [403, 429, 500, 503] and i < max_retries - 1:\n                            wait_time = (2 ** i) + random.uniform(0, 1) # \u00dcstel geri \u00e7ekilme + rastgele jitter\n                            print(f\"API hatas\u0131 ({e.resp.status}). {wait_time:.2f} saniye sonra tekrar deniyorum...\")\n                            time.sleep(wait_time)\n                        else:\n                            raise # Son deneme veya beklenmedik hata, yeniden f\u0131rlat\n                raise Exception(\"API \u00e7a\u011fr\u0131s\u0131 maksimum deneme say\u0131s\u0131na ula\u015ft\u0131.\")\n\n            # \u00d6rnek kullan\u0131m:\n            # messages = make_api_call_with_retry(service.users().messages().list, userId='me', labelIds=['INBOX'])\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p>Bu kod par\u00e7ac\u0131\u011f\u0131, a\u011f hatalar\u0131 veya kota a\u015f\u0131mlar\u0131 durumunda API \u00e7a\u011fr\u0131lar\u0131n\u0131 daha dayan\u0131kl\u0131 hale getirir.<\/p>\n<h3>\u00d6nbellekleme (Caching): Tekrar Tekrar Ayn\u0131 Veriyi \u00c7ekmeyin<\/h3>\n<p>S\u0131k s\u0131k de\u011fi\u015fmeyen veya belirli bir s\u00fcre g\u00fcncelli\u011fini koruyan veriler i\u00e7in \u00f6nbellekleme kullanmak performans\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rabilir ve API kota kullan\u0131m\u0131n\u0131 azalt\u0131r. \u00d6rne\u011fin, Gmail etiketleri (labels) veya kullan\u0131c\u0131 profili bilgileri genellikle s\u0131k de\u011fi\u015fmez. Bu verileri yerel olarak bir s\u00fcre \u00f6nbelle\u011fe alabilirsiniz.<\/p>\n<p><strong>Performans Kar\u015f\u0131la\u015ft\u0131rmas\u0131: Direkt API \u00c7a\u011fr\u0131s\u0131 vs. \u00d6nbellekli \u00c7\u00f6z\u00fcm<\/strong><\/p>\n<table>\n<thead>\n<tr>\n<th>Y\u00f6ntem<\/th>\n<th>Avantajlar<\/th>\n<th>Dezavantajlar<\/th>\n<th>Kullan\u0131m Alan\u0131<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Direkt API \u00c7a\u011fr\u0131s\u0131<\/strong><\/td>\n<td>Her zaman en g\u00fcncel veri, basit uygulama<\/td>\n<td>Y\u00fcksek API kotas\u0131 t\u00fcketimi, a\u011f gecikmesi, daha yava\u015f<\/td>\n<td>Anl\u0131k, kritik ve s\u00fcrekli g\u00fcncel kalmas\u0131 gereken veriler<\/td>\n<\/tr>\n<tr>\n<td><strong>Yerel \u00d6nbellek (Dosya\/Veritaban\u0131)<\/strong><\/td>\n<td>Daha h\u0131zl\u0131 yan\u0131t s\u00fcresi, API kotas\u0131 tasarrufu, \u00e7evrimd\u0131\u015f\u0131 \u00e7al\u0131\u015fma (s\u0131n\u0131rl\u0131)<\/td>\n<td>Veri g\u00fcncelli\u011fi sorunlar\u0131, \u00f6nbellek invalidasyonu karma\u015f\u0131kl\u0131\u011f\u0131, ek depolama ihtiyac\u0131<\/td>\n<td>Az de\u011fi\u015fen veriler (etiketler, kullan\u0131c\u0131 profili), ge\u00e7mi\u015f veriler<\/td>\n<\/tr>\n<tr>\n<td><strong>Bellek \u0130\u00e7i \u00d6nbellek (Python dict)<\/strong><\/td>\n<td>En h\u0131zl\u0131 yan\u0131t, basit implementasyon<\/td>\n<td>Uygulama yeniden ba\u015flat\u0131ld\u0131\u011f\u0131nda kaybolur, s\u0131n\u0131rl\u0131 depolama<\/td>\n<td>Sadece tek bir oturumda s\u0131k\u00e7a tekrar eden veriler i\u00e7in<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Basit bir bellek i\u00e7i \u00f6nbellek \u00f6rne\u011fi:<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-python\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            # ... (\u00f6nceki kod) ...\n            _labels_cache = {} # Bellek i\u00e7i \u00f6nbellek\n\n            def get_labels_with_cache(service, user_id='me'):\n                \"\"\"Gmail etiketlerini \u00f6nbellekten veya API'den getirir.\"\"\"\n                if not _labels_cache:\n                    try:\n                        labels_response = make_api_call_with_retry(service.users().labels().list, userId=user_id)\n                        _labels_cache.update({label['id']: label['name'] for label in labels_response.get('labels', [])})\n                        print(\"Etiketler API'den \u00e7ekildi ve \u00f6nbelle\u011fe al\u0131nd\u0131.\")\n                    except Exception as e:\n                        print(f\"Etiketler \u00e7ekilirken hata olu\u015ftu: {e}\")\n                else:\n                    print(\"Etiketler \u00f6nbellekten getirildi.\")\n                return _labels_cache\n\n            # Kullan\u0131m:\n            # labels = get_labels_with_cache(service)\n            # print(labels.get('INBOX'))\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p>Daha geli\u015fmi\u015f \u00f6nbellekleme stratejileri i\u00e7in Redis gibi harici bir \u00f6nbellek \u00e7\u00f6z\u00fcm\u00fc de d\u00fc\u015f\u00fcnebilirsiniz.<\/p>\n<h3>Asenkron \u0130\u015flemler: Paralel \u00c7al\u0131\u015fma \u0130le H\u0131zlanma<\/h3>\n<p>Birden fazla e-posta i\u015fleme, \u00e7ok say\u0131da mesaj\u0131 okuma veya birden fazla API \u00e7a\u011fr\u0131s\u0131 yapma gibi senaryolarda asenkron programlama veya \u00e7oklu i\u015f par\u00e7ac\u0131\u011f\u0131 (threading) \/ \u00e7oklu s\u00fcre\u00e7 (multiprocessing) kullanmak performans\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rabilir.<\/p>\n<p>Python'da <code>asyncio<\/code> veya <code>concurrent.futures<\/code> mod\u00fclleri bu konuda yard\u0131mc\u0131 olabilir. \u00d6rne\u011fin, y\u00fczlerce e-postay\u0131 tek tek almak yerine, bunlar\u0131 paralel olarak \u00e7ekmek genel i\u015flem s\u00fcresini k\u0131saltabilir.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-python\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            import concurrent.futures\n\n            def fetch_single_message_details(service, user_id, message_id):\n                \"\"\"Tek bir e-postan\u0131n detaylar\u0131n\u0131 \u00e7eker.\"\"\"\n                try:\n                    return service.users().messages().get(userId=user_id, id=message_id).execute()\n                except Exception as e:\n                    print(f\"Mesaj {message_id} \u00e7ekilirken hata: {e}\")\n                    return None\n\n            def fetch_multiple_message_details_parallel(service, user_id, message_ids):\n                \"\"\"Birden fazla e-postan\u0131n detaylar\u0131n\u0131 paralel olarak \u00e7eker.\"\"\"\n                with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:\n                    # fetch_single_message_details fonksiyonunu her mesaj kimli\u011fi i\u00e7in paralel \u00e7al\u0131\u015ft\u0131r\n                    futures = [executor.submit(fetch_single_message_details, service, user_id, msg_id) for msg_id in message_ids]\n                    \n                    results = []\n                    for future in concurrent.futures.as_completed(futures):\n                        result = future.result()\n                        if result:\n                            results.append(result)\n                return results\n\n            # Kullan\u0131m:\n            # message_ids_to_fetch = ['id1', 'id2', 'id3'] # \u00d6rnek mesaj kimlikleri\n            # detailed_messages = fetch_multiple_message_details_parallel(service, 'me', message_ids_to_fetch)\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p>Bu y\u00f6ntem, [\u0130leri D\u00fczey] optimizasyonlar i\u00e7in kritik bir yakla\u015f\u0131md\u0131r. Ancak, \u00e7oklu i\u015f par\u00e7ac\u0131\u011f\u0131 veya s\u00fcre\u00e7 kullan\u0131rken API kotalar\u0131na dikkat etmek ve ayn\u0131 anda \u00e7ok fazla istek g\u00f6ndermemek \u00f6nemlidir. Aksi takdirde, oran s\u0131n\u0131rlamalar\u0131na tak\u0131labilirsiniz.<\/p>\n<p>Uygulaman\u0131z\u0131n performans\u0131n\u0131 izlemek i\u00e7in zamanlama (profiling) ara\u00e7lar\u0131 kullanmay\u0131 da unutmay\u0131n. Python'da <code>cProfile<\/code> gibi mod\u00fcller, kodunuzun hangi b\u00f6l\u00fcmlerinin daha fazla zaman ald\u0131\u011f\u0131n\u0131 belirlemenize yard\u0131mc\u0131 olabilir.<\/p>\n<\/section>\n<section>\n<h2>\u00dcretime \u00c7\u0131karma ve Da\u011f\u0131t\u0131m: G\u00fcvenli CLI'\u0131n\u0131z\u0131 Kullan\u0131c\u0131larla Nas\u0131l Payla\u015f\u0131rs\u0131n\u0131z?<\/h2>\n<p>CLI uygulaman\u0131z\u0131 geli\u015ftirdikten ve g\u00fcvenli\u011fini sa\u011flad\u0131ktan sonra, son ad\u0131m onu \u00fcretime \u00e7\u0131karmak ve kullan\u0131c\u0131lar\u0131n eri\u015fimine sunmakt\u0131r. Bu a\u015fama, uygulaman\u0131n farkl\u0131 ortamlarda sorunsuz \u00e7al\u0131\u015fmas\u0131n\u0131, ba\u011f\u0131ml\u0131l\u0131klar\u0131n do\u011fru y\u00f6netilmesini ve g\u00fcvenli bir \u015fekilde da\u011f\u0131t\u0131lmas\u0131n\u0131 i\u00e7erir. Bu b\u00f6l\u00fcm, [\u0130leri D\u00fczey] konulara odaklanarak, Docker, konteynerle\u015ftirme ve bulut da\u011f\u0131t\u0131m\u0131na dair bilgiler sunacakt\u0131r.<\/p>\n<h3>Konteynerle\u015ftirme ile Kolay Da\u011f\u0131t\u0131m: Docker<\/h3>\n<p>Uygulaman\u0131z\u0131 Docker konteynerlerine sarmak, ba\u011f\u0131ml\u0131l\u0131k sorunlar\u0131n\u0131 ortadan kald\u0131r\u0131r ve uygulaman\u0131z\u0131n her ortamda (geli\u015ftirme, test, \u00fcretim) ayn\u0131 \u015fekilde \u00e7al\u0131\u015fmas\u0131n\u0131 garanti eder. Bu, \"bir kez yaz, her yerde \u00e7al\u0131\u015ft\u0131r\" felsefesini destekler.<\/p>\n<p>Projenizin k\u00f6k dizininde bir <code>Dockerfile<\/code> olu\u015fturun:<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-dockerfile\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            # Ubuntu tabanl\u0131 hafif bir Python g\u00f6r\u00fcnt\u00fcs\u00fc kullan\n            FROM python:3.9-slim-buster\n\n            # \u00c7al\u0131\u015fma dizinini ayarla\n            WORKDIR \/app\n\n            # Ba\u011f\u0131ml\u0131l\u0131klar\u0131 kopyala ve y\u00fckle\n            COPY requirements.txt .\n            RUN pip install --no-cache-dir -r requirements.txt\n\n            # Uygulama kodunu kopyala\n            COPY . .\n\n            # Ortam de\u011fi\u015fkenlerini ayarla (g\u00fcvenlik i\u00e7in bu \u015fekilde belirtmek yerine,\n            # Docker run komutunda -e ile ge\u00e7mek veya Docker Secrets kullanmak daha iyidir)\n            # ENV GOOGLE_CLIENT_ID=\"your_client_id\"\n            # ENV GOOGLE_CLIENT_SECRET=\"your_client_secret\"\n\n            # CLI uygulamas\u0131n\u0131 \u00e7al\u0131\u015ft\u0131racak varsay\u0131lan komut\n            CMD [\"python\", \"gmail_cli.py\"]\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p><code>requirements.txt<\/code> dosyan\u0131z\u0131n da t\u00fcm Python ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131z\u0131 i\u00e7erdi\u011finden emin olun:<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-text\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            google-api-python-client\n            google-auth-oauthlib\n            google-auth-httplib2\n            keyring # E\u011fer keyring kullan\u0131yorsan\u0131z\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p>\u015eimdi Docker imaj\u0131n\u0131 olu\u015fturabilir ve \u00e7al\u0131\u015ft\u0131rabilirsiniz:<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-bash\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            # \u0130maj\u0131 olu\u015ftur\n            docker build -t gmail-cli-app .\n\n            # Konteyneri \u00e7al\u0131\u015ft\u0131r (credentials.json dosyan\u0131z\u0131 mount etmeniz gerekebilir)\n            # \u0130lk \u00e7al\u0131\u015ft\u0131rmada OAuth ak\u0131\u015f\u0131 i\u00e7in taray\u0131c\u0131 a\u00e7ma gereksinimi\n            # CLI uygulamalar\u0131 i\u00e7in bu genellikle interaktif bir s\u00fcre\u00e7tir.\n            # \u00dcretimde headless (ba\u015fs\u0131z) \u00e7al\u0131\u015ft\u0131rmak i\u00e7in \u00f6nceden kimlik do\u011frulanm\u0131\u015f bir 'token.pickle'\n            # veya keyring tabanl\u0131 bir yakla\u015f\u0131m kullan\u0131lmal\u0131d\u0131r.\n            docker run -it --rm -v $(pwd)\/credentials.json:\/app\/credentials.json \\\n                                 -v $(pwd)\/token.pickle:\/app\/token.pickle \\\n                                 gmail-cli-app\n\n            # E\u011fer headless \u00e7al\u0131\u015facaksa ve token \u00f6nceden olu\u015fturulmu\u015fsa:\n            # docker run -it --rm -v $(pwd)\/token.pickle:\/app\/token.pickle \\\n            #                          -e GOOGLE_CLIENT_ID=\"your_id\" \\\n            #                          -e GOOGLE_CLIENT_SECRET=\"your_secret\" \\\n            #                          gmail-cli-app\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p><code>-v<\/code> bayra\u011f\u0131 ile yerel dosya sistemindeki <code>credentials.json<\/code> ve <code>token.pickle<\/code> dosyalar\u0131n\u0131 konteyner i\u00e7ine mount ediyoruz. Bu, uygulaman\u0131n kimlik do\u011frulama bilgilerine eri\u015fmesini sa\u011flar. \u00dcretim ortamlar\u0131nda <code>token.pickle<\/code> dosyas\u0131n\u0131n \u00f6nceden olu\u015fturulmu\u015f ve g\u00fcvenli bir \u015fekilde saklanm\u0131\u015f olmas\u0131 esast\u0131r.<\/p>\n<h3>Bulut Ortam\u0131nda Da\u011f\u0131t\u0131m ve Otomasyon<\/h3>\n<p>CLI uygulaman\u0131z\u0131 buluta da\u011f\u0131tmak, otomasyon i\u015f ak\u0131\u015flar\u0131 ve s\u00fcrekli \u00e7al\u0131\u015fma i\u00e7in idealdir. \u00d6rne\u011fin, bir cron i\u015fi olarak her g\u00fcn belirli bir saatte \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flayabilirsiniz.<\/p>\n<ul>\n<li>\n            <strong>Google Cloud Run \/ AWS Fargate:<\/strong> Konteynerle\u015ftirilmi\u015f uygulaman\u0131z\u0131 sunucusuz (serverless) bir ortamda kolayca da\u011f\u0131tabilirsiniz. Bu servisler, sadece uygulama \u00e7al\u0131\u015f\u0131rken kaynak t\u00fcketir ve otomatik \u00f6l\u00e7eklenir. Gmail CLI'n\u0131z\u0131n belirli bir HTTP iste\u011fi \u00fczerine tetiklenmesi veya bir zamanlay\u0131c\u0131 taraf\u0131ndan \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131 gerekti\u011finde harika bir \u00e7\u00f6z\u00fcmd\u00fcr.\n          <\/li>\n<li>\n            <strong>Kubernetes:<\/strong> Daha b\u00fcy\u00fck ve karma\u015f\u0131k da\u011f\u0131t\u0131mlar i\u00e7in Kubernetes, konteynerlerin orkestrasyonu, \u00f6l\u00e7eklenmesi ve y\u00f6netimi i\u00e7in end\u00fcstri standard\u0131d\u0131r. CLI uygulaman\u0131z\u0131 bir Kubernetes Job olarak \u00e7al\u0131\u015ft\u0131rabilir ve belirli bir takvime g\u00f6re tetikleyebilirsiniz.\n          <\/li>\n<li>\n            <strong>CI\/CD (S\u00fcrekli Entegrasyon\/S\u00fcrekli Da\u011f\u0131t\u0131m):<\/strong> Geli\u015ftirme s\u00fcrecinizi otomatikle\u015ftirmek i\u00e7in GitHub Actions, GitLab CI\/CD veya Jenkins gibi ara\u00e7lar\u0131 kullanabilirsiniz. Bu, kodunuz her de\u011fi\u015fti\u011finde uygulaman\u0131z\u0131n otomatik olarak test edilmesini, bir Docker imaj\u0131na d\u00f6n\u00fc\u015ft\u00fcr\u00fclmesini ve bulut ortam\u0131na da\u011f\u0131t\u0131lmas\u0131n\u0131 sa\u011flar.\n          <\/li>\n<\/ul>\n<div class=\"interactive-box\">\n          Uzman \u0130pucu: CI\/CD s\u00fcre\u00e7lerinizde hassas bilgileri (Client ID, Client Secret) do\u011frudan betiklere yazmak yerine, CI\/CD platformunuzun sundu\u011fu g\u00fcvenli de\u011fi\u015fken y\u00f6netim sistemlerini (secrets management) kullan\u0131n.\n        <\/div>\n<h3>Mobil Uyumlu HTML \u00c7\u0131kt\u0131s\u0131 (CLI \u0130\u00e7in Bir Vizyon)<\/h3>\n<p>CLI uygulamalar\u0131 genellikle metin tabanl\u0131 \u00e7\u0131kt\u0131lar \u00fcretir. Ancak, baz\u0131 durumlarda (\u00f6rne\u011fin, CLI taraf\u0131ndan bir rapor olu\u015fturuldu\u011funda veya bir web aray\u00fcz\u00fcne y\u00f6nlendirildi\u011finde) mobil uyumlu HTML \u00e7\u0131kt\u0131lar olu\u015fturmak faydal\u0131 olabilir. Bu, kullan\u0131c\u0131n\u0131n bu \u00e7\u0131kt\u0131lar\u0131 mobil cihaz\u0131nda daha rahat g\u00f6r\u00fcnt\u00fclemesini sa\u011flar. Bir CLI uygulamas\u0131 do\u011frudan HTML \u00fcretmeyebilir, ancak \u00fcretti\u011fi veriyi HTML'e d\u00f6n\u00fc\u015ft\u00fcrecek ba\u015fka bir servise g\u00f6nderebilir veya \u00e7\u0131kt\u0131y\u0131 taray\u0131c\u0131da a\u00e7acak bir komut i\u00e7erebilir.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-html\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            <!DOCTYPE html>\n            <html lang=\"tr\">\n            <head>\n                <meta charset=\"UTF-8\">\n                <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n                <title>Gmail CLI Raporu<\/title>\n                <style>\n                    body { font-family: sans-serif; margin: 20px; line-height: 1.6; color: #333; }\n                    .container { max-width: 800px; margin: auto; padding: 15px; border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n                    h1 { color: #0056b3; }\n                    .message-item { background-color: #f9f9f9; border-left: 5px solid #007bff; margin-bottom: 10px; padding: 10px; border-radius: 4px; }\n                    .message-item strong { display: block; margin-bottom: 5px; color: #333; }\n                    .message-item span { font-size: 0.9em; color: #666; }\n\n                    \/* Mobil uyumluluk *\/\n                    @media (max-width: 600px) {\n                        .container {\n                            margin: 10px;\n                            padding: 10px;\n                        }\n                        h1 {\n                            font-size: 1.5em;\n                        }\n                        .message-item {\n                            padding: 8px;\n                            font-size: 0.9em;\n                        }\n                    }\n                <\/style>\n            <\/head>\n            <body>\n                <div class=\"container\">\n                    <h1>Son E-posta \u00d6zeti (CLI Raporu)<\/h1>\n                    <div class=\"message-item\">\n                        <strong>Konu: Yeni Bildirim Geldi<\/strong>\n                        <span>G\u00f6nderen: Sistem &lt;no-reply@example.com&gt;<\/span><br>\n                        <span>Tarih: 2023-10-27 10:30<\/span>\n                    <\/div>\n                    <!-- Daha fazla e-posta \u00f6\u011fesi buraya dinamik olarak eklenebilir -->\n                <\/div>\n            <\/body>\n            <\/html>\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p>Bu HTML yap\u0131s\u0131, CLI uygulaman\u0131z taraf\u0131ndan toplanan verileri g\u00fczel bir \u015fekilde g\u00f6rselle\u015ftirmek i\u00e7in kullan\u0131labilir. CLI, bu HTML'i bir dosyaya yazabilir ve kullan\u0131c\u0131ya bu dosyay\u0131 taray\u0131c\u0131da a\u00e7ma se\u00e7ene\u011fi sunabilir. B\u00f6ylece, CLI'\u0131n metin odakl\u0131 do\u011fas\u0131, g\u00f6rsel bir raporlama yetene\u011fi ile zenginle\u015ftirilebilir.<\/p>\n<p>\u00dcretime \u00e7\u0131karma ve da\u011f\u0131t\u0131m s\u00fcre\u00e7lerini otomatikle\u015ftirmek, uygulaman\u0131z\u0131n g\u00fcvenilirli\u011fini ve s\u00fcrd\u00fcr\u00fclebilirli\u011fini art\u0131racakt\u0131r. Bu, [\u0130leri D\u00fczey] bir geli\u015ftiricinin ba\u015far\u0131l\u0131 bir proje i\u00e7in mutlaka benimsemesi gereken yakla\u015f\u0131mlard\u0131r.<\/p>\n<\/section>\n<section>\n<h2>Vaka \u00c7al\u0131\u015fmas\u0131: Otomatik E-posta Raporlama Sistemi Olu\u015fturmak<\/h2>\n<p>\u015eimdiye kadar \u00f6\u011frendiklerimizi bir araya getirerek ger\u00e7ek d\u00fcnya bir senaryo \u00fczerinde, [\u0130leri D\u00fczey] seviyesinde bir vaka \u00e7al\u0131\u015fmas\u0131 yapal\u0131m. Bir \u015firketin g\u00fcnl\u00fck sat\u0131\u015f raporlar\u0131n\u0131 otomatik olarak belirli bir e-posta grubuna g\u00f6ndermesi gerekti\u011fini varsayal\u0131m. Bu raporlar, bir veritaban\u0131ndan \u00e7ekilen kritik i\u015f bilgilerini i\u00e7erecek ve e-posta eki olarak g\u00f6nderilecektir. Bu, bir Gmail CLI uygulamas\u0131n\u0131n otomasyon g\u00fcc\u00fcn\u00fc sergilemek i\u00e7in harika bir \u00f6rnektir.<\/p>\n<h3>Senaryo Detaylar\u0131<\/h3>\n<ul>\n<li>Her i\u015f g\u00fcn\u00fc sonunda (\u00f6rne\u011fin saat 17:00'de) tetiklenecek.<\/li>\n<li>Bir veritaban\u0131ndan (\u00f6rne\u011fin PostgreSQL) g\u00fcnl\u00fck sat\u0131\u015f verilerini \u00e7ekecek.<\/li>\n<li>Bu verileri g\u00fczel bi\u00e7imlendirilmi\u015f bir CSV veya PDF raporuna d\u00f6n\u00fc\u015ft\u00fcrecek.<\/li>\n<li>Raporu bir e-posta eki olarak belirlenmi\u015f al\u0131c\u0131lara (\u00f6rn. <code>sales_team@example.com<\/code>) g\u00f6nderecek.<\/li>\n<li>Ba\u015far\u0131l\u0131 ve ba\u015far\u0131s\u0131z g\u00f6nderim durumlar\u0131n\u0131 loglayacak.<\/li>\n<li>Kimlik do\u011frulama i\u00e7in \u00f6nceden yetkilendirilmi\u015f bir Gmail hesab\u0131 kullanacak.<\/li>\n<\/ul>\n<h3>Uygulama Ad\u0131mlar\u0131 ve Kazan\u0131mlar<\/h3>\n<h4>1. Veritaban\u0131 Entegrasyonu (Python \u00d6rne\u011fi)<\/h4>\n<p>Sat\u0131\u015f verilerini \u00e7ekmek i\u00e7in <code>psycopg2<\/code> (PostgreSQL i\u00e7in) veya <code>sqlite3<\/code> (basit bir SQLite veritaban\u0131 i\u00e7in) gibi bir k\u00fct\u00fcphane kullanaca\u011f\u0131z. Basitlik ad\u0131na burada SQLite kullanal\u0131m.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-python\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            import sqlite3\n            import pandas as pd # Veri manip\u00fclasyonu ve CSV i\u00e7in\n\n            def get_daily_sales_data(db_path='sales.db'):\n                conn = sqlite3.connect(db_path)\n                query = \"SELECT product_name, quantity, price FROM sales WHERE sale_date = DATE('now')\"\n                df = pd.read_sql_query(query, conn)\n                conn.close()\n                return df\n\n            # \u00d6rnek veritaban\u0131 ve veri olu\u015fturma (ilk \u00e7al\u0131\u015ft\u0131rma i\u00e7in)\n            def setup_database(db_path='sales.db'):\n                conn = sqlite3.connect(db_path)\n                cursor = conn.cursor()\n                cursor.execute(\"\"\"\n                    CREATE TABLE IF NOT EXISTS sales (\n                        id INTEGER PRIMARY KEY AUTOINCREMENT,\n                        product_name TEXT NOT NULL,\n                        quantity INTEGER NOT NULL,\n                        price REAL NOT NULL,\n                        sale_date DATE NOT NULL\n                    )\n                \"\"\")\n                # \u00d6rnek veri ekleme\n                cursor.execute(\"INSERT INTO sales (product_name, quantity, price, sale_date) VALUES (?, ?, ?, DATE('now'))\", ('Laptop', 1, 1200.00))\n                cursor.execute(\"INSERT INTO sales (product_name, quantity, price, sale_date) VALUES (?, ?, ?, DATE('now'))\", ('Mouse', 5, 25.00))\n                cursor.execute(\"INSERT INTO sales (product_name, quantity, price, sale_date) VALUES (?, ?, ?, DATE('now', '-1 day'))\", ('Keyboard', 2, 75.00)) # D\u00fcn\u00fcn verisi\n                conn.commit()\n                conn.close()\n                print(\"Veritaban\u0131 haz\u0131rland\u0131 ve \u00f6rnek veri eklendi.\")\n\n            if __name__ == '__main__':\n                setup_database()\n                sales_df = get_daily_sales_data()\n                print(\"\\nG\u00fcnl\u00fck Sat\u0131\u015f Verileri:\")\n                print(sales_df)\n          <\/pre>\n<p><\/code>\n        <\/div>\n<p>Bu kod, g\u00fcnl\u00fck sat\u0131\u015f verilerini SQLite veritaban\u0131ndan \u00e7eker ve bir Pandas DataFrame olarak d\u00f6nd\u00fcr\u00fcr. Pandas, veri i\u015fleme ve rapor olu\u015fturma i\u00e7in son derece g\u00fc\u00e7l\u00fc bir k\u00fct\u00fcphanedir.<\/p>\n<h4>2. Rapor Olu\u015fturma ve E-posta Eki Haz\u0131rlama<\/h4>\n<p>\u00c7ekti\u011fimiz verileri bir CSV dosyas\u0131na yaz\u0131p e-posta eki olarak haz\u0131rlayaca\u011f\u0131z.<\/p>\n<div class=\"kod-blogu\">\n<pre><code class=\"language-python\">\n            <button class=\"copy-button\" onclick=\"copyCode(this)\">Kopyala<\/button>\n            # ... (\u00f6nceki get_gmail_service, create_message, send_message fonksiyonlar\u0131 ve db kodlar\u0131) ...\n            from email.mime.multipart import MIMEMultipart\n            from email.mime.base import MIMEBase\n            from email import encoders\n            import datetime\n\n            def create_message_with_attachment(sender, to, subject, message_text, file_path, file_name):\n                \"\"\"E-posta mesaj\u0131na dosya eki ekleyerek MIME format\u0131nda olu\u015fturur.\"\"\"\n                msg = MIMEMultipart()\n                msg['to'] = to\n                msg['from'] = sender\n                msg['subject'] = subject\n\n                msg.attach(MIMEText(message_text))\n\n                part = MIMEBase('application', 'octet-stream')\n                with open(file_path, 'rb') as file:\n                    part.set_payload(file.read())\n                encoders.encode_base64(part)\n                part.add_header('Content-Disposition', f'attachment; filename={file_name}')\n                msg.attach(part)\n\n                return {'raw': base64.urlsafe_b64encode(msg.as_bytes()).decode()}\n\n            def generate_sales_report(sales_df, output_filename=\"daily_sales_report.csv\"):\n                \"\"\"Pandas DataFrame'i CSV olarak kaydeder.\"\"\"\n                if not sales_df.empty:\n                    sales_df.to_csv(output_filename, index=False)\n                    print(f\"Rapor '{output_filename}' ba\u015far\u0131yla olu\u015fturuldu.\")\n                    return output_filename\n                else:\n                    print(\"G\u00fcnl\u00fck sat\u0131\u015f verisi bulunamad\u0131, rapor olu\u015fturulmad\u0131.\")\n                    return None\n\n            # ... (ana k\u0131s\u0131mda kullanmak i\u00e7in) ...\n            if __name__ == '__main__':\n                # ... (get_gmail_service ve setup_database \u00e7a\u011fr\u0131lar\u0131) ...\n                \n                sales_df = get_daily_sales_data()\n                report_file = generate_sales_report(sales_df)\n\n                if report_file:\n                    sender_email = \"your_gmail_account@gmail.com\" # G\u00f6nderen e-posta adresi\n                    recipient_email = \"sales_team@example.com\" # Al\u0131c\u0131 e-posta adresi\n                    email_subject = f\"G\u00fcnl\u00fck Sat\u0131\u015f Raporu - {datetime.date.today()}\"\n                    email_body = f\"Merhaba Sat\u0131\u015f Ekibi,\\n\\nEkte {datetime.date.today()} tarihli g\u00fcnl\u00fck sat\u0131\u015f raporumuz bulunmaktad\u0131r.\\n\\nSayg\u0131lar\u0131m\u0131zla,\\nOtomatik Rapor Sistemi\"\n\n                    message_with_attachment = create_message_with_attachment(\n                        sender_email, recipient_email, email_subject, email_body, report_file, report_file\n                    )\n                    send_message(service, 'me', message_with_attachment)\n                else:\n                    logging.info(\"Sat\u0131\u015f raporu g\u00f6nderilmedi: Veri yok.\")\n\n          <\/pre>\n<p><\/code>\n        <\/div>\n<h4>3. Da\u011f\u0131t\u0131m ve Otomasyon<\/h4>\n<p>Bu CLI uygulamas\u0131n\u0131 Docker konteynerine al\u0131p bir bulut ortam\u0131nda otomatik olarak \u00e7al\u0131\u015ft\u0131rmak en iyi yakla\u015f\u0131md\u0131r:<\/p>\n<ol>\n<li>\n            <strong>Dockerize Etme:<\/strong> Yukar\u0131da g\u00f6sterildi\u011fi gibi bir <code>Dockerfile<\/code> olu\u015fturun. <code>pandas<\/code>, <code>psycopg2<\/code> (e\u011fer PostgreSQL kullan\u0131yorsan\u0131z) gibi ba\u011f\u0131ml\u0131l\u0131klar\u0131 <code>requirements.txt<\/code>'ye ekleyin.\n          <\/li>\n<li>\n            <strong>Pre-Authenticated Token:<\/strong> \u0130lk kez uygulamay\u0131 yerel olarak \u00e7al\u0131\u015ft\u0131r\u0131p <code>token.pickle<\/code> dosyas\u0131n\u0131 olu\u015fturun. Bu dosyay\u0131 daha sonra Docker imaj\u0131na dahil edebilir veya g\u00fcvenli bir \u015fekilde konteynere mount edebilirsiniz.\n          <\/li>\n<li>\n            <strong>Veritaban\u0131 Ba\u011flant\u0131s\u0131:<\/strong> Veritaban\u0131 bilgileri (host, user, password) i\u00e7in ortam de\u011fi\u015fkenleri kullan\u0131n ve bunlar\u0131 Docker run komutunda veya Docker Compose\/Kubernetes manifestlerinde belirtin.\n          <\/li>\n<li>\n            <strong>Zamanlanm\u0131\u015f \u00c7al\u0131\u015ft\u0131rma:<\/strong><\/p>\n<ul>\n<li><strong>Bulut Tabanl\u0131 Zamanlay\u0131c\u0131lar:<\/strong> Google Cloud Scheduler veya AWS EventBridge gibi servisleri kullanarak, her g\u00fcn belirli bir saatte Docker konteynerinizi (\u00f6rne\u011fin Cloud Run'da) tetikleyecek bir i\u015f olu\u015fturun.<\/li>\n<li><strong>Kubernetes CronJob:<\/strong> E\u011fer Kubernetes kullan\u0131yorsan\u0131z, bir CronJob tan\u0131mlayarak uygulaman\u0131z\u0131n belirli aral\u0131klarla \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flayabilirsiniz.<\/li>\n<\/ul>\n<\/li>\n<li>\n            <strong>G\u00fcvenlik ve \u0130zleme:<\/strong> Uygulaman\u0131n loglar\u0131n\u0131 bulut tabanl\u0131 bir loglama servisine (Google Cloud Logging, AWS CloudWatch) g\u00f6nderin. Ola\u011fan d\u0131\u015f\u0131 durumlar veya hatalar i\u00e7in uyar\u0131lar ayarlay\u0131n. Kimlik bilgileri i\u00e7in Google Secret Manager veya Kubernetes Secrets kullan\u0131n.\n          <\/li>\n<\/ol>\n<h4>Kazan\u0131mlar:<\/h4>\n<ul>\n<li><strong>Zaman Tasarrufu:<\/strong> G\u00fcnl\u00fck manuel raporlama s\u00fcrecini ortadan kald\u0131r\u0131r.<\/li>\n<li><strong>Hata Azaltma:<\/strong> \u0130nsan hatas\u0131 riskini minimize eder.<\/li>\n<li><strong>\u00d6l\u00e7eklenebilirlik:<\/strong> Farkl\u0131 raporlama ihtiya\u00e7lar\u0131 i\u00e7in kolayca geni\u015fletilebilir.<\/li>\n<li><strong>G\u00fcvenlik:<\/strong> Hassas verilere do\u011frudan eri\u015fim yerine API ve g\u00fcvenli token'lar kullan\u0131l\u0131r.<\/li>\n<li><strong>Esneklik:<\/strong> CLI olmas\u0131 sayesinde farkl\u0131 otomasyon betiklerine kolayca entegre edilebilir.<\/li>\n<\/ul>\n<p>Bu vaka \u00e7al\u0131\u015fmas\u0131, [\u0130leri D\u00fczey] bir geli\u015ftiricinin Gmail CLI uygulamas\u0131n\u0131 nas\u0131l g\u00fc\u00e7l\u00fc bir otomasyon arac\u0131 haline getirebilece\u011fini ve \u00fcretim ortam\u0131nda g\u00fcvenle \u00e7al\u0131\u015ft\u0131rabilece\u011fini g\u00f6stermektedir.<\/p>\n<\/section>\n<section>\n<h2>Sonu\u00e7: G\u00fcvenli Gmail CLI Geli\u015ftirmenin Gelece\u011fi ve S\u0131k\u00e7a Sorulan Sorular<\/h2>\n<p>Bu kapsaml\u0131 rehber boyunca, g\u00fcvenli bir Gmail CLI uygulamas\u0131n\u0131 s\u0131f\u0131rdan geli\u015ftirmekten ba\u015flayarak, temel kavramlar\u0131 anlamaya, kodlamaya, g\u00fcvenlik katmanlar\u0131n\u0131 g\u00fc\u00e7lendirmeye, performans\u0131 optimize etmeye ve nihayetinde \u00fcretime \u00e7\u0131karma s\u00fcre\u00e7lerini ad\u0131m ad\u0131m inceledik. Komut sat\u0131r\u0131 aray\u00fczlerinin sundu\u011fu esneklik ve otomasyon g\u00fcc\u00fcn\u00fc Gmail API'nin geni\u015f yetenekleriyle birle\u015ftirerek, e-posta y\u00f6netimi s\u00fcre\u00e7lerinizi radikal bir \u015fekilde d\u00f6n\u00fc\u015ft\u00fcrebilece\u011finizi g\u00f6rd\u00fck. G\u00fcvenli\u011fin bu denli kritik bir rol oynad\u0131\u011f\u0131 bir alanda, OAuth 2.0, token y\u00f6netimi ve en az ayr\u0131cal\u0131k prensibi gibi konulara \u00f6zel bir vurgu yapt\u0131k. Uygulaman\u0131z\u0131 konteynerle\u015ftirmek (Docker) ve bulut ortam\u0131nda da\u011f\u0131tmak (Cloud Run, Kubernetes) gibi modern yakla\u015f\u0131mlarla, projenizin s\u00fcrd\u00fcr\u00fclebilirli\u011fini ve \u00f6l\u00e7eklenebilirli\u011fini nas\u0131l art\u0131rabilece\u011finizi \u00f6\u011frendiniz.<\/p>\n<p>Gmail CLI uygulamalar\u0131n\u0131n gelece\u011fi, yapay zeka entegrasyonlar\u0131, daha geli\u015fmi\u015f otomasyon senaryolar\u0131 ve farkl\u0131 platformlarla sorunsuz entegrasyon y\u00f6n\u00fcnde ilerlemektedir. \u00d6rne\u011fin, b\u00fcy\u00fck dil modelleri (LLM) ile entegre bir CLI, e-postalar\u0131n\u0131z\u0131 \u00f6zetleyebilir, taslaklar olu\u015fturabilir veya belirli bir konudaki bilgileri otomatik olarak ay\u0131klayabilir. Bu, geli\u015ftiriciler i\u00e7in s\u00fcrekli yeni f\u0131rsatlar sunan heyecan verici bir aland\u0131r.<\/p>\n<p>Umar\u0131z bu rehber, kendi g\u00fcvenli Gmail CLI projelerinizi ba\u015flatman\u0131z ve ba\u015far\u0131l\u0131 bir \u015fekilde tamamlaman\u0131z i\u00e7in size sa\u011flam bir temel sa\u011flam\u0131\u015ft\u0131r. Unutmay\u0131n, geli\u015ftirme yolculu\u011funuzda daima \u00f6\u011frenmeye ve kendinizi geli\u015ftirmeye devam edin. Daha fazla bilgi ve \u00f6rnek projeler i\u00e7in <a href=\"https:\/\/fatihsoysal.com\" target=\"_blank\">Fatih Soysal'\u0131n web sitesini<\/a> ziyaret edebilirsiniz.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<ol>\n<li>\n<h4>Gmail CLI uygulamas\u0131 geli\u015ftirmek i\u00e7in hangi programlama dilini se\u00e7meliyim?<\/h4>\n<p><strong>Cevap:<\/strong> Python ve Node.js bu t\u00fcr uygulamalar i\u00e7in en pop\u00fcler ve uygun dillerdendir. Python, temiz s\u00f6zdizimi ve zengin k\u00fct\u00fcphane ekosistemi (<code>google-api-python-client<\/code>) sayesinde otomasyon ve betikleme g\u00f6revleri i\u00e7in harikad\u0131r. Node.js ise asenkron yap\u0131s\u0131 ve performansl\u0131 I\/O yetenekleri ile \u00f6ne \u00e7\u0131kar. Se\u00e7iminiz, projenizin gereksinimlerine, ekibinizin uzmanl\u0131\u011f\u0131na ve ki\u015fisel tercihinize ba\u011fl\u0131d\u0131r.<\/p>\n<\/li>\n<li>\n<h4>OAuth 2.0 kimlik bilgilerimi (Client ID, Client Secret) nas\u0131l g\u00fcvenli bir \u015fekilde saklayabilirim?<\/h4>\n<p><strong>Cevap:<\/strong> Bu bilgiler asla do\u011frudan kodunuza veya kaynak kontrol sisteminize (Git) dahil edilmemelidir. Yerel geli\u015ftirme i\u00e7in ortam de\u011fi\u015fkenleri veya bir <code>.env<\/code> dosyas\u0131 kullan\u0131labilir (ancak <code>.env<\/code> dosyas\u0131 <code>.gitignore<\/code>'a eklenmelidir). \u00dcretim ortamlar\u0131 i\u00e7in ise i\u015fletim sistemi anahtar depolar\u0131 (keyring), bulut tabanl\u0131 anahtar y\u00f6netimi servisleri (AWS Secrets Manager, Google Secret Manager) veya Docker Secrets\/Kubernetes Secrets gibi \u00e7\u00f6z\u00fcmler tercih edilmelidir. <code>credentials.json<\/code> dosyas\u0131n\u0131 da kesinlikle genel depolara y\u00fcklemeyin.<\/p>\n<\/li>\n<li>\n<h4>Uygulamam\u0131n API kotalar\u0131n\u0131 a\u015fmas\u0131n\u0131 nas\u0131l engellerim?<\/h4>\n<p><strong>Cevap:<\/strong> API kotalar\u0131n\u0131 a\u015fman\u0131n en yayg\u0131n \u00e7\u00f6z\u00fcm\u00fc \"Exponential Backoff\" (\u00dcstel Geri \u00c7ekilme) stratejisini uygulamakt\u0131r. Bu, ba\u015far\u0131s\u0131z API isteklerinden sonra artan s\u00fcrelerle tekrar denemeyi i\u00e7erir. Ayr\u0131ca, s\u0131k de\u011fi\u015fmeyen veriler i\u00e7in \u00f6nbellekleme (caching) kullanarak API \u00e7a\u011fr\u0131s\u0131 say\u0131s\u0131n\u0131 azaltabilirsiniz. Google Cloud Console'dan API kota kullan\u0131m\u0131n\u0131z\u0131 d\u00fczenli olarak izlemek de \u00f6nemlidir.<\/p>\n<\/li>\n<li>\n<h4>Gmail API'ye tam eri\u015fim yerine hangi izinleri istemeliyim?<\/h4>\n<p><strong>Cevap:<\/strong> \"En Az Ayr\u0131cal\u0131k Prensibi\"ne uyun. Uygulaman\u0131z\u0131n sadece ihtiya\u00e7 duydu\u011fu en dar kapsaml\u0131 izinleri (scopes) isteyin. \u00d6rne\u011fin, sadece e-posta g\u00f6nderecekseniz <code>https:\/\/www.googleapis.com\/auth\/gmail.send<\/code> iznini isteyin, t\u00fcm Gmail verilerine eri\u015fim sa\u011flayan <code>https:\/\/www.googleapis.com\/auth\/gmail.full<\/code> iznini de\u011fil. Bu, bir g\u00fcvenlik ihlali durumunda olu\u015fabilecek zarar\u0131 s\u0131n\u0131rlar.<\/p>\n<\/li>\n<li>\n<h4>Uygulamam\u0131 Docker ile konteynerle\u015ftirmek neden \u00f6nemlidir?<\/h4>\n<p><strong>Cevap:<\/strong> Konteynerle\u015ftirme, uygulaman\u0131z\u0131n t\u00fcm ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 izole bir pakete (konteyner) sarmalayarak \"bir kez yaz, her yerde \u00e7al\u0131\u015ft\u0131r\" prensibini sa\u011flar. Bu, geli\u015ftirme, test ve \u00fcretim ortamlar\u0131 aras\u0131nda tutarl\u0131l\u0131\u011f\u0131 garanti eder, da\u011f\u0131t\u0131m s\u00fcre\u00e7lerini basitle\u015ftirir ve ba\u011f\u0131ml\u0131l\u0131k \u00e7ak\u0131\u015fmalar\u0131n\u0131 ortadan kald\u0131r\u0131r. Bulut ortamlar\u0131nda (\u00f6rne\u011fin Google Cloud Run, AWS Fargate, Kubernetes) kolayca da\u011f\u0131t\u0131labilir ve y\u00f6netilebilir hale gelir.<\/p>\n<\/li>\n<\/ol>\n<\/section>\n<\/article>\n<p>  <\/main><\/p>\n<footer>\n<p>Yazar: Fatih Soysal<\/p>\n<\/footer>\n<p>  <script>\n    function copyCode(button) {\n      const pre = button.parentElement;\n      const code = pre.querySelector('code');\n      const text = code.textContent;<\/p>\n<p>      navigator.clipboard.writeText(text).then(() => {\n        button.textContent = 'Kopyaland\u0131!';\n        setTimeout(() => {\n          button.textContent = 'Kopyala';\n        }, 2000);\n      }).catch(err => {\n        console.error('Kopyalama ba\u015far\u0131s\u0131z oldu:', err);\n      });\n    }\n  <\/script><br \/>\n<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi E-posta y\u00f6netimini komut sat\u0131r\u0131na ta\u015f\u0131yarak verimlili\u011finizi art\u0131r\u0131n! Bu rehber, g\u00fcvenli&hellip;","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":[1342],"tags":[],"class_list":{"0":"post-30287","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-ai","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>G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi<\/title>\n<meta name=\"description\" content=\"E-posta y\u00f6netimini komut sat\u0131r\u0131na ta\u015f\u0131yarak verimlili\u011finizi art\u0131r\u0131n! Bu rehber, g\u00fcvenli bir Gmail CLI uygulamas\u0131n\u0131 ba\u015ftan sona nas\u0131l geli\u015ftirece\u011finizi ve \u00fcretime nas\u0131l ge\u00e7irece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131kl\u0131yor.\" \/>\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\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi\" \/>\n<meta property=\"og:description\" content=\"E-posta y\u00f6netimini komut sat\u0131r\u0131na ta\u015f\u0131yarak verimlili\u011finizi art\u0131r\u0131n! Bu rehber, g\u00fcvenli bir Gmail CLI uygulamas\u0131n\u0131 ba\u015ftan sona nas\u0131l geli\u015ftirece\u011finizi ve \u00fcretime nas\u0131l ge\u00e7irece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131kl\u0131yor.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-09-26T11:02:19+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=\"40 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi\",\"datePublished\":\"2025-09-26T11:02:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/\"},\"wordCount\":5665,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"AI\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/\",\"name\":\"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-09-26T11:02:19+00:00\",\"description\":\"E-posta y\u00f6netimini komut sat\u0131r\u0131na ta\u015f\u0131yarak verimlili\u011finizi art\u0131r\u0131n! Bu rehber, g\u00fcvenli bir Gmail CLI uygulamas\u0131n\u0131 ba\u015ftan sona nas\u0131l geli\u015ftirece\u011finizi ve \u00fcretime nas\u0131l ge\u00e7irece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131kl\u0131yor.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi\"}]},{\"@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":"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi","description":"E-posta y\u00f6netimini komut sat\u0131r\u0131na ta\u015f\u0131yarak verimlili\u011finizi art\u0131r\u0131n! Bu rehber, g\u00fcvenli bir Gmail CLI uygulamas\u0131n\u0131 ba\u015ftan sona nas\u0131l geli\u015ftirece\u011finizi ve \u00fcretime nas\u0131l ge\u00e7irece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131kl\u0131yor.","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\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/","og_locale":"tr_TR","og_type":"article","og_title":"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi","og_description":"E-posta y\u00f6netimini komut sat\u0131r\u0131na ta\u015f\u0131yarak verimlili\u011finizi art\u0131r\u0131n! Bu rehber, g\u00fcvenli bir Gmail CLI uygulamas\u0131n\u0131 ba\u015ftan sona nas\u0131l geli\u015ftirece\u011finizi ve \u00fcretime nas\u0131l ge\u00e7irece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131kl\u0131yor.","og_url":"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-09-26T11:02:19+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"40 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi","datePublished":"2025-09-26T11:02:19+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/"},"wordCount":5665,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["AI"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/","url":"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/","name":"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-09-26T11:02:19+00:00","description":"E-posta y\u00f6netimini komut sat\u0131r\u0131na ta\u015f\u0131yarak verimlili\u011finizi art\u0131r\u0131n! Bu rehber, g\u00fcvenli bir Gmail CLI uygulamas\u0131n\u0131 ba\u015ftan sona nas\u0131l geli\u015ftirece\u011finizi ve \u00fcretime nas\u0131l ge\u00e7irece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131kl\u0131yor.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/guvenli-gmail-cli-gelistirme-projeyi-uretime-tasima-rehberi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"G\u00fcvenli Gmail CLI Geli\u015ftirme: Projeyi \u00dcretime Ta\u015f\u0131ma Rehberi"}]},{"@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\/30287","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=30287"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/30287\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=30287"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=30287"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=30287"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}