Yazışmalar
`threads.list`, `list_all`, `iterate`, `get`, `update`, `trash`, `snooze`, `unsnooze` ve `list_attachments`.
Okuma
page = client.threads.list( folder: "inbox", query: "from:ada", label_ids: ["INBOX", "IMPORTANT"], limit: 25) if page.next_cursor next_page = client.threads.list(folder: "inbox", cursor: page.next_cursor) puts next_page.items.sizeend thread = client.threads.get("CAHk7pQ2x9LmZ4-mail.example.com")puts thread[:messageCount], thread[:hasUnread], thread[:totalReplies]API konuşma dizilerini bir pageToken ile sayfalar. İstemci, diğer her listede olduğu gibi bunu size next_cursor olarak verir ve cursor: olarak geri alır; list_all ve iterate onu sizin için izler. Opaktır: size verileni geri geçirin ve asla kendiniz oluşturmayın.
Liste filtreleri snake_case biçiminde Ruby anahtar kelimeleridir (label_ids:, date_from:); bir istek gövdesinin alanları ise API'nin camelCase adlarını korur (update üzerinde addLabelIds:). Bir konuşma dizisi Symbol anahtarlı bir Hash olarak döner; bu yüzden thread[:messageCount] sayıyı okur.
last_week = client.threads.list_all( sort: "oldest", date_from: Time.now - (7 * 86_400), date_to: Time.now, from_contacts: true)puts last_week.size client.threads.iterate(sort: "sender") do |thread| puts thread[:id]endsort:, date_from:, date_to: ve from_contacts: konuşma dizisi listesinin kendi denetimleridir. sort: değeri newest, oldest, sender ya da subject olur ve OpenEmail::THREAD_SORTS bunları adlandırır. Tarihler bir Time, bir DateTime ya da saat ve ofset içeren bir ISO 8601 dizesi alır ve her iki uç da dahildir. Bir Ruby Date çıplak bir tarih olarak gönderilir ve bu alanlar onu 422 ile reddeder. from_contacts: true, en yeni iletisi kayıtlı bir kişiden gelen postaları tutar. Her sıralama, hiçbir konuşma dizisini atlamadan ya da tekrarlamadan sonuna kadar sayfalanır.
list_all son sayfa geldiğinde tek bir Array döndürür. iterate her konuşma dizisini bir bloğa verir ve bir sonraki sayfayı yalnızca döngü ihtiyaç duyduğunda getirir. Blok olmadan bir Enumerator döndürür; böylece first(10) ya da lazy ihtiyaç duydukları şeyi alır almaz durur.
Düzenleme
thread_id = "CAHk7pQ2x9LmZ4-mail.example.com" client.threads.update(thread_id, read: true, addLabelIds: ["USER_DONE"], removeLabelIds: ["INBOX"]) client.threads.trash(thread_id)client.threads.snooze(thread_id, Time.now + 86_400)client.threads.unsnooze(thread_id)Okunma durumu buradaki her arka uçta bir etikettir; bu yüzden etiket listeleriyle birlikte taşınır ve ikisini birden ayarladığınızda sıra sabittir: kaldırmalar eklemelerden önce uygulanır, bu yüzden iki listede de bulunan bir kimlik sonunda konuşma dizisinde kalır. Üç alandan en az biri bulunmalıdır.
addLabelIds, labels.list içindeki kimlikleri ve ARCHIVE ve STARRED gibi sistem kimliklerini alır. Hiçbir etiketi belirtmeyen bir kimlik oluşturulmaz, 422 label_not_found ile reddedilir; bu yüzden etiketi önce labels.create ile oluşturun. client.threads.list(folder: "USER_DONE"), hangi klasörde olursa olsun bir etiketi taşıyan her konuşma dizisini listeler.
Bir iletideki ekler
files = client.threads.list_attachments("CAHk7pQ2x9LmZ4-mail.example.com", "message_4c1b257a") files.each do |file| puts "#{file[:filename]} #{file[:contentType]} #{file[:size]}" File.binwrite(file[:filename], file[:content].unpack1("m")) unless file[:content].to_s.empty?endlist_attachments Hash'lerden oluşan bir Array döndürür. content base64'tür ve unpack1("m") onu ikili bir String'e dönüştürür; saklanan baytlar bulunamadığında boş bir dizedir, bu yüzden çözmeden önce uzunluğunu kontrol edin. Şifreli bir iletinin şifreli metni bu listededir ve diğer her dosya gibi indirilir. PGP/MIME sürüm parçası ve ayrık imza ise listede yoktur. Bunların yalnızca kimlikleri encryption.parts içinde tutulur.
Şifreli olarak gelen bir ileti
Bu gem ne şifreler ne de şifre çözer. Başkasının şifrelediği bir iletiyi açamaz ve şifreli bir ileti gönderemez. Gönderme isteği bir şifreleme işareti taşıyorsa reddedilir, çünkü anahtarı olmayan bir istemcinin böyle bir iddiada bulunmaya hakkı yoktur. OpenEmail uygulamasında üretilen anahtarlar onları üreten tarayıcıda yaşar ve buraya hiçbir şekilde ulaşmaz. O tarayıcı mühürlü bir iletiyi açtığında düz metin tarayıcıda kalır ve bu çağrının okuduğu saklı ileti hâlâ şifreli metindir. threads.get size tanınmış hâliyle zarfı verir. PGP ya da S/MIME sarmalıyla gelen bir ileti bir encryption Hash'i taşır; böylece elinize tutuşturulan tek şey boş bir decodedBody olmaktan çıkar. encryption, API'nin bir iletide taahhüt ettiği tek alandır, çünkü yokluğunu tahmine dayanarak atlatamayacağınız alan odur.
thread = client.threads.get("CAHk7pQ2x9LmZ4-mail.example.com") thread[:messages].each do |message| next unless message[:encryption] next unless OpenEmail.sealed?(message) warn "cannot read this one: #{message[:encryption][:format]}"endAlanın varlığına göre değil, OpenEmail.sealed? ile dallanın. Beş biçimden ikisi, pgp-signed ve smime-signed, ayrık bir imzanın yanında açık hâlde gelen bir gövdeyi tanımlar; bu yüzden varlığa göre kapı koymak, kimsenin gizlemesi gerekmeyen postayı gizler ve kullanıcı ne onu görebilir ne de açıklayabilir. OpenEmail.sealed? tam da bu nedenle vardır. Sunucu mühürlü kümeyi bir kez bildirir, gem'deki kopya aynı kaynaktan üretilir ve elle yazılmış üçüncü bir kopya, zamanla kayan kopyadır. OpenEmail::MESSAGE_ENCRYPTION_FORMATS beş biçimin tamamını adlandırır.
Yokluk, düz metin demek değildir. encryption, algılama yayımlanmadan önce saklanan her iletide ve algılayıcının hiç çalışmadığı bir yoldan posta kutusuna ulaşan her şeyde eksiktir. Kimsenin bakmadığını kaydeder; bu, postaya değil kapsamımıza dair bir olgudur ve hiçbir şey onu geriye dönük doldurmaz.
Bunların diğerlerinden ayrıldığı nokta
- Bir konuşma dizisinin
messagesiçindeki her kayıt, posta kutusunun sakladığı Hash'tir ve sabit bir alan listesi yoktur. Daha fazlasını vaat etmek, istemcinin kimsenin yapmadığı bir normalleştirmeyi iddia etmesi olurdu.encryptionyine de API'nin taahhüt ettiği tek alandır, çünkü ona göre dallanamayan bir istemci mühürlü bir iletiyi boş bir ileti olarak okur. - Aslına uygun şekilde karşılanamayan bir istek, doğru görünüp sessizce yanlış olan bir yanıt değil,
OpenEmail::ValidationErrorolarak fırlatılan 422capability_unsupportedverir.
Parametreler: threads.list
folderString- Hangi klasörün listeleneceği. Sunucu bunu varsayılan olarak `inbox` alır; bu yüzden belirtmemek, listelemeyi her şeye genişletmek yerine daraltır. Sorgu, `in:` ile ya da `is:sent` gibi bir klasör `is:` ifadesiyle kendisi bir klasör adlandırmadığı sürece, bu parametre bir `query:` aramasına da uygulanır.
queryString- Posta kutusu arama sözdizimi. Düz sözcüklerin tümü geçmelidir ve her biri gevşek eşleşir: büyük/küçük harf, aksanlar ve ayırıcılar yok sayılır, daha uzun bir sözcüğün parçası da sayılır; bu yüzden hem `min` hem de `ben jamin` “Benjamin”i bulur. Tırnak içindeki bir ifade, büyük/küçük harf ve aksanlar dışında yazıldığı gibi eşleşir; bu yüzden `"ben jamin"` “Ben-Jamin”i bulmaz ve aranacak başka bir şey kaldığında dolgu sözcükleri düşürülür. Hiçbir şey tam olarak eşleşmediğinde onun yerine yakın yazımlar döndürülür; dolayısıyla `benjimin` “Benjamin”i bulur: düz bir sözcük ya da `from:`, `to:`, `cc:`, `subject:`, `body:`, `filename:` veya `label:` değeri, dört ile yedi harfliyse bir sözcüğün başından bir yazım hatasıyla (değişmiş, eksik, fazla ya da yer değiştirmiş bir harf), sekiz ya da daha fazla harfliyse iki hatayla ayrılabilir. Tırnak içindeki bir ifade, rakam içeren bir sözcük, daha kısa bir sözcük ve dışlanan bir sözcük ise yine yalnızca tam eşleşir ve sonraki sayfalar da aynı biçimde arar. `from:ada`, `label:Invoices`, `is:unread`, `has:pdf`, `before:2026/01/31` ve `older_than:1y` gibi operatörlerle daraltın ve bunları `OR`, parantezler ve başa konan bir `-` ile birleştirin. Aramanın kullanamadığı bir değer daraltma yapmak yerine yok sayılır. Sözcükler ile `from:`, `to:`, `cc:`, `subject:` ve `body:` operatörleri en son iletinin göndericisini, alıcılarını, konusunu ve gövdesinin işaretlemeden arındırılmış ilk 4.000 karakterini okur; `filename:` ve `has:` ise tüm yazışmadaki her eki okur, etiketler ve klasörler de tüm yazışmayı okur. Filtresiz listelemenin okuduğu indeksin aynısını daraltır. Mühürlü iletiler hiçbir gövde metni saklamaz; bu yüzden yalnızca göndericileri, alıcıları ve konuları eşleşebilir. Düz bir sözcük, hangi iletiyle gelmiş olursa olsun, yazışmadaki herhangi bir ekin adıyla da eşleşir.
label_idsString or Array<String>- Listelemeyi bu etiketleri taşıyan konuşma dizileriyle sınırlar. Uç nokta virgülle ayrılmış bir dize alır ve istemci bir Array ya da Set'i sizin için bu dizeye birleştirir. Kaç etiket belirttiğinize dair bir sınır yoktur.
limitInteger- Döndürülecek konuşma dizisi sayısı; 1 ile 100 arası. Belirtilmezse işleyici 25 kullanır. Varsayılan şemada değil işleyicide tanımlıdır; bu yüzden eksik bir değer ile açıkça verilmiş 25 aynı şekilde davranır.
cursorString- Önceki sayfanın `next_cursor` değeri, olduğu gibi geri geçirilir. Diğer her listenin kullandığı adla API'nin `pageToken` değeridir ve opaktır; bu yüzden asla oluşturmayın ya da düzenlemeyin.
Yanıt: OpenEmail::Page
itemsArray<Hash>- Bu sayfadaki her konuşma dizisi için API'nin `data` zarfından çıkarılmış bir Hash. Her biri yalnızca bir `object` işaretçisi ve bir `id` içerir. Listeleme konu, önizleme metni, katılımcılar ya da etiketler taşımaz; daha fazlası için istediğiniz konuşma dizileri üzerinde `threads.get` çağırmanız gerekir.
items[].idString- Konuşma dizisinin kimliği; `item[:id]` olarak okunur ve `threads.get`, `threads.update` ve diğerlerine değiştirilmeden verilir. Satır ister filtrelenmiş bir listelemeden ister bir `query:` aramasından gelsin, aynı kimliktir.
has_more?Boolean- Başka bir sayfa olup olmadığı; API bunu belirtiyorsa API'den alınır, belirtmiyorsa `next_cursor` değerinden türetilir.
next_cursorString or nil- Sonraki sayfa için `cursor:` olarak geri gönderilecek API'nin `nextPageToken` değeri; başka sayfa yoksa nil. Boş bir token nil'e normalleştirilir; bu yüzden `if page.next_cursor` ile bir nil denetimi aynı sonucu verir.