teklif-kutusu
Skill32 starsChanged 5 months agoMITView on GitHub
Google Tablolar'daki ana müşteri listesinde durumu "Bekliyor" olan ilk firma için uçtan uca teklif hazırlar - şablondan belge üretir, içinde bulunulan ayın klasörüne koyar, PDF'ini alır, PDF ekli taslak mail oluşturur (GÖNDERMEZ) ve listedeki satırı günceller. Kullanıcı "teklif hazırla", "sıradaki teklifi çıkar", "bekleyen firmaya teklif yap", "teklif kutusu" dediğinde ya da /teklif-kutusu çağrıldığında kullan.
Files
Teklif Kutusu
Bekleyen bir firma için teklif belgesi + PDF + taslak mail üretir ve ana listeyi günceller. Tek bir firma işler: listede durumu "Bekliyor" olan ilk kayıt.
Değişmez kurallar
Bu kurallar her koşulda geçerlidir. Kullanıcı aksini söylemedikçe çiğnenmez.
- Mail asla gönderilmez. Her zaman taslak olarak bırakılır.
drafts.createkullan;drafts.send,messages.sendveyagws gmail +sendbu beceride ASLA kullanılmaz. - Şablona hiçbir adımda dokunulmaz. Şablon salt okunurdur. Her teklif için önce
files.copyile kopya çıkarılır, doldurma yalnızca kopyada yapılır. Şablonun kendisindedocuments.batchUpdateçalıştırmak yasaktır. - Ana liste Google Tablolar dosyasıdır. Arşivdeki
.xlsxdosyasına yazmaya çalışma — Google Sheets API bir Excel dosyasını düzenleyemez, hata döner. Sadeceana_liste.idile çalış. - Tablo güncellemesi zorunludur. Tablo güncellenmeden iş bitmiş sayılmaz. Belge ve PDF üretilip tablo güncellenmediyse iş YARIM kalmıştır; bunu kullanıcıya açıkça söyle ve eksik güncellemeyi tamamla.
- Dosyalar kök klasörde bırakılmaz. Belge de PDF de her zaman içinde bulunulan ayın
klasörüne konur. Klasör yoksa
YYYY-MMadıyla ana klasörün altında oluşturulur. - Firma satırı sütun başlığına bakarak bulunur. Hücre veya kolon numarası varsayma. Başlık satırını oku, aradığın sütunun indeksini oradan hesapla.
- "Bekliyor" durumunda firma yoksa hiçbir şey üretme. Belge, PDF, mail, hiçbiri. Sadece "bekleyen kayıt yok" de ve dur.
- Dosya adresleri beceriye yazılmaz. Bütün ID'ler ve linkler
teklif-ayarlari.jsondosyasından okunur. Bu dosyadaki hiçbir ID bu SKILL.md içine kopyalanmaz — böylece başka biri kendi ayar dosyasıyla aynı beceriyi kullanabilir.
Ek güvenlik kuralı: birden fazla satır eşleşirse hiçbir şey yazma. Firma adıyla tabloda birden çok satır eşleşiyorsa dur, kullanıcıya hangisini kastettiğini sor.
Ön koşullar
gwsPATH'te olmalı (gws --version).- Google hesabı bağlı olmalı (
gws auth statusiçindetoken_valid: true). Bağlı değilse kullanıcıyagws auth login --services drive,docs,sheets,gmailkomutunu söyle; giriş akışını kullanıcı onaylamadan başlatma. - Çalışma dizininde
teklif-ayarlari.jsonbulunmalı. Yoksa kullanıcıya sor, uydurma.
Ayar dosyası
Bütün adresler buradan okunur. Beklenen alanlar:
| Yol | Ne için |
ana_liste.id | Ana liste (Google Tablolar) |
ana_liste.sekme | Sekme adı |
sablon.id | Teklif şablonu (Google Dokümanlar) |
klasorler.ana.id | Kök "Teklif Kutusu" klasörü |
sablon.bosluklar[] | Boşluk adı ve hangi sütundan besleneceği |
sablon.bosluklar içindeki kaynak alanı Musteriler.<sütun> biçimindeyse değer o
sütundan okunur; hesaplanir ise kural alanındaki tarife göre hesaplanır
(örn. gönderim tarihi + 1 ay).
Akış
0. Ayarları oku
teklif-ayarlari.json dosyasını oku, ID'leri oradan al. Eksik alan varsa dur ve sor.
1. Bekleyen kaydı seç
scripts/kayit-sec.js çalıştır. Bu script ana listeyi okur, başlık satırından sütun
indekslerini bulur, durum sütunu "Bekliyor" olan ilk satırı seçer ve firma adıyla
kaç satır eşleştiğini kontrol eder.
node ~/.claude/skills/teklif-kutusu/scripts/kayit-sec.js teklif-ayarlari.json secim.json- Çıktıda
bekleyen: 0ise → "bekleyen kayıt yok" de ve dur. Hiçbir şey üretme. - Çıktıda
cokludeğeri 1'den büyükse → dur, kullanıcıya sor. Hiçbir şey yazma.
2. Ay klasörünü hazırla
Bugünün YYYY-MM değerini hesapla. Ana klasörün altında bu adda klasör var mı bak:
gws drive files list --params "$(cat <<JSON
{"q":"'ANA_KLASOR_ID' in parents and name = 'YYYY-MM' and mimeType = 'application/vnd.google-apps.folder' and trashed = false","fields":"files(id,name)"}
JSON
)"Yoksa oluştur; varsa mevcut ID'yi kullan, ikinci bir tane açma.
gws drive files create --params '{"fields":"id,name"}' --json "$(cat <<JSON
{"name":"YYYY-MM","mimeType":"application/vnd.google-apps.folder","parents":["ANA_KLASOR_ID"]}
JSON
)"3. Belgeyi üret
Şablonun kopyasını doğrudan ay klasöründe oluştur — böylece ayrı taşıma adımı gerekmez:
gws drive files copy --params '{"fileId":"SABLON_ID","fields":"id,name,webViewLink"}' --json "$(cat <<JSON
{"name":"Teklif - FIRMA_ADI","parents":["AY_KLASOR_ID"]}
JSON
)"Sonra boşlukları kopyada doldur. Her boşluk için bir replaceAllText isteği gönder;
istekleri tek batchUpdate içinde topla. İstek gövdesini bir dosyaya yazıp
--json "$(cat dosya.json)" ile vermek, tırnak sorunlarını önler.
gws docs documents batchUpdate --params '{"documentId":"KOPYA_ID"}' --json "$(cat istek.json)"istek.json biçimi:
{ "requests": [
{ "replaceAllText": { "containsText": { "text": "{{firma}}", "matchCase": true },
"replaceText": "Firma Adı" } }
] }Doldurma sonrası belgeyi geri oku ve hiç {{ kalmadığını doğrula. Kalan varsa
kullanıcıya söyle.
4. PDF üret
gws drive files export --params '{"fileId":"KOPYA_ID","mimeType":"application/pdf"}' -o "_gecici.pdf"
gws drive +upload "_gecici.pdf" --name "Teklif - FIRMA_ADI" --parent "AY_KLASOR_ID"PDF de ay klasörüne gider. Yükleme sonrası _gecici.pdf dosyasını sil.
5. Taslak mail
scripts/mail-olustur.js ile MIME mesajını üret, sonra yükle:
node ~/.claude/skills/teklif-kutusu/scripts/mail-olustur.js secim.json _ek.pdf _mesaj.eml
gws gmail users drafts create --params '{"userId":"me"}' --upload "_mesaj.eml" --upload-content-type "message/rfc822"Metin kısa ve nazik olmalı: görüşmede konuşulan iş için teklifin ekte olduğu ve teklifin kaç gün geçerli olduğu. Gün sayısı gönderim ve geçerlilik tarihleri arasından hesaplanır, sabit yazılmaz.
Sonuçta labelIds içinde DRAFT olduğunu doğrula. Taslağı geri okuyup ekin yerinde
olduğunu kontrol et. Geçici .eml ve .pdf dosyalarını sil.
6. Tabloyu güncelle — ATLANMAZ
Sütunları başlık adından, satırı firma adından bul. Şu dört alanı yaz:
| Sütun | Değer |
durum | Taslak hazır |
gonderim_tarihi | bugün (gg.aa.yyyy) |
teklif_linki | belgenin bağlantısı |
pdf | PDF'in bağlantısı |
gws sheets spreadsheets values update --params '{"spreadsheetId":"LISTE_ID","range":"SEKME!F2:H2","valueInputOption":"RAW"}' --json "$(cat deger.json)"Bitişik sütunları tek aralıkta yazabilirsin (örn. durum, teklif_linki,
gonderim_tarihi yan yanaysa F2:H2). Yazma sonrası satırı geri oku ve doğrula.
7. Raporla
Kullanıcıya şunları göster:
- hangi firma seçildi ve neden (ilk "Bekliyor"),
- hangi boşluğa ne yazıldı,
- belge ve PDF nereye gitti,
- mailde ne yazıyor, kime gidecek, hangi ek var ve taslakta olduğu,
- tabloda hangi hücreler güncellendi (öncesi → sonrası).
Bilinen tuzaklar
gwsçıktısının ilk satırıUsing keyring backend: keyringolabilir. JSON parse etmeden öncegrep -av keyringile ayıkla.-o/--outputçalışma dizini dışına yazamaz. Geçici dosyaları çalışma dizininde oluştur, işin sonunda sil.- Gmail komutlarında
userIdzorunludur:--params '{"userId":"me"}'. - Sheets yazarken
valueInputOptionRAW olmalı.USER_ENTEREDtarihi seri numarasına çevirip görünümü bozabilir. - Tarih biçimi
gg.aa.yyyy(ör. 15.09.2026); tabloda bu biçim kullanılıyor. - Türkçe karakterli mail konusu RFC 2047 (
=?UTF-8?B?...?=), ek dosya adı RFC 2231 (filename*=UTF-8''...) ile kodlanmalı.mail-olustur.jsbunu zaten yapar. - Mail ekine
.pdfuzantısı eklenir ki alıcı açabilsin; Drive'daki dosyanın adı uzantısız olabilir. Drive'da aynı adda iki dosya (belge + PDF) bulunması sorun değil. files.copysırasındamimeTypevererek biçim dönüştürülebilir (xlsx → Google Sheets, docx → Google Dokümanlar). Kaynak dosya bundan etkilenmez.- Uzun JSON gövdelerini komut satırına gömmek yerine dosyaya yazıp
--json "$(cat f.json)"ile ver; Türkçe karakterler ve iç içe tırnaklar böyle bozulmaz.
In this repository5 other files it gives its agents.
- deploy-appSkill
- fatura-kutusuSkill
- hyperframes-studioSkill
- prd-yazSkill
- seo-expertSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

