Belgelere geç
Ruby

Yapılandırma

İstemci oluşturmanın üç yolu, tüm seçenekler ve bir istek gönderilmeden önce nelerin reddedildiği.

Seçenekler

clients.rb
require "openemail" OpenEmail.init(api_key: ENV.fetch("OPENEMAIL_API_KEY"))OpenEmail.me.ping pinned = OpenEmail::Client.new(api_key: ENV.fetch("OPENEMAIL_API_KEY"), base_url: "https://api.openemail.uk")quick = OpenEmail::Client.new(ENV.fetch("OPENEMAIL_API_KEY"))billing = OpenEmail.create_client(api_key: ENV.fetch("BILLING_API_KEY")) p pinned.mode, quick.mode, billing.mode
Giriş noktasıSize ne verir
OpenEmail.init(...)Paylaşılan istemciyi yapılandırır ve döndürür. O andan itibaren her dosyada ve her iş parçacığında OpenEmail.client o istemcidir ve belirtmediğiniz her şey ortamdan okunur.
OpenEmail.client, OpenEmail.emails, OpenEmail.threads ve diğer tüm ad alanlarıPaylaşılan istemci ve ad alanlarına giden kısayollar. init öncesinde kullanılırsa ilk çağrıda kendini OPENEMAIL_API_KEY ve OPENEMAIL_BASE_URL değerlerinden kurar.
OpenEmail.reset_clientPaylaşılan istemciyi bırakır; böylece bir sonraki çağrı ortamdan yeni bir istemci kurar.
OpenEmail.create_client(...)Aynı ortam yedeğine sahip ayrı bir istemci: paylaşılanın yanında ikinci bir anahtar için ya da kendi kodunuzun tutup başka yerlere aktardığı bir istemci için.
OpenEmail::Client.new(...) or OpenEmail::Client.new(api_key)Tam olarak geçirdiğiniz değerlerden kurulan ayrı bir istemci. Ortamı okumaz, bu yüzden api_key: ya da access_token: gerektirir. OpenEmail.new aynı çağrıdır.
options.rb
OpenEmail.init(  api_key: ENV.fetch("OPENEMAIL_API_KEY"),  base_url: "https://api.openemail.uk",  timeout: 30,  max_retries: 2,  adapter: OpenEmail::NetHttpAdapter.new(max_idle: 8, keep_alive_timeout: 2),  headers: {"X-Team" => "billing"},  user_agent: "billing-service/1.4",  disable_update_notice: true)
SeçenekVarsayılanNotlar
api_key:OPENEMAIL_API_KEYinit, create_client ve paylaşılan istemci tarafından ortamdan okunur. oe_live_ ya da oe_test_ ile başlamalıdır. İlk argüman olarak da verilebilir, ama ikisi birden olamaz.
access_token:OPENEMAIL_ACCESS_TOKENBir OAuth erişim tokenı ya da call çağrısına yanıt verip bir token döndüren herhangi bir nesne. Aşağıdaki “OAuth erişim tokenları” bölümüne bakın. Bir anahtar ya da bir token geçirin, asla ikisini birden değil.
base_url:https://api.openemail.ukYa da OPENEMAIL_BASE_URL. Sondaki eğik çizgiler kırpılır; init ve create_client, çıplak bir konak adının önüne https://, bu makinedeki bir konağın önüne ise http:// ekler: localhost, bir 127.x.x.x adresi ya da ::1. Bir kimlik bilgisi hiçbir zaman düz http üzerinden başka bir konağa gönderilmez ve 0.0.0.0 ya da [::] istemci kurulurken hata fırlatır, çünkü bunlar bir sunucunun dinlediği adreslerdir, istek gönderilecek adresler değildir.
timeout:30Çağrı başına değil, deneme başına saniye. Varsayılan adaptörle bu süre yalnızca başlıkları değil, bağlanmayı ve gövdenin tamamını okumayı da kapsar. 0 bunu kapatır. files.upload, o çağrıda timeout: geçirmediğiniz sürece en az 600 saniye bekler.
max_retries:2Tekrarlanması güvenli çağrılarda ilk denemeden sonraki ek denemeler. Çağrı başına değil, istemcide ayarlanır. 0 yeniden denemeleri kapatır.
adapter:OpenEmail::NetHttpAdapter.newHTTP katmanı. Varsayılan katman, konak başına en fazla 8 boşta bağlantıyı her biri 2 saniye boyunca tutar; max_idle: ve keep_alive_timeout: bunu değiştirir. call(request) çağrısına yanıt veren herhangi bir nesne onun yerini alabilir; bir test ağ olmadan bu şekilde çalışır.
headers:{}Her istekte gönderilir.
user_agent:openemail-ruby/<version>Her istekte gönderilir.
disable_update_notice:falseRubyGems'te daha yeni bir sürüm için süreç başına bir kez yapılan denetimi atlar. Denetim yalnızca standart çıktı bir terminal olduğunda çalışır ve OPENEMAIL_DISABLE_UPDATE_NOTICE da onu kapatır.

Ortam değişkenleri

DeğişkenNe yapar
OPENEMAIL_API_KEYNe api_key: ne de access_token: geçirdiğinizde init, create_client ve paylaşılan istemcinin kullandığı anahtar.
OPENEMAIL_ACCESS_TOKENBir OAuth erişim tokenı. Yalnızca hiçbir kimlik bilgisi geçirmediğinizde ve OPENEMAIL_API_KEY ayarlanmamışsa okunur, yani ortamdaki bir anahtar önceliklidir.
OPENEMAIL_BASE_URLHiçbiri geçirilmediğinde kullanılan temel URL. localhost:2222 gibi çıplak bir konağa şeması eklenir.
OPENEMAIL_DISABLE_UPDATE_NOTICEBoş olmayan herhangi bir değer, süreçteki tüm istemciler için güncelleme bildirimini kapatır.
HTTPS_PROXY ve NO_PROXY ya da https_proxy ve no_proxyVarsayılan adaptörün üzerinden bağlandığı proxy ve doğrudan bağlanılan konaklar. Aşağıdaki “Proxy'ler” bölümüne bakın.

OpenEmail::Client.new ilk üçünden hiçbirini okumaz; bu yüzden bu şekilde kurulan bir istemci ortamdaki bir anahtarı asla yanlışlıkla almaz. Ayarlanmış ama boş olan bir değişken ayarlanmamış sayılır.

Göndermeden önce neleri reddeder

Bunlar, ilk gönderiminizde kafa karıştırıcı bir hata olarak ortaya çıkmak yerine, yanlış değerin bulunduğu satırdan ArgumentError fırlatır. Hata iletisi neyin yanlış olduğunu ve bunun yerine ne geçirileceğini söyler ve bir kimlik bilgisini asla tekrarlamaz.

ReddedilenNeden
Hiç kimlik bilgisi yokNe api_key: ne de access_token: geçirildi ve init ile create_client için iki değişkenden hiçbiri de ayarlanmadı; dolayısıyla kimlik doğrulamak için hiçbir şey yok. İstemci kurulurken fırlatılır.
Bir anahtar ve bir token birlikteHer istek tek bir kimlik bilgisi taşır; bu yüzden istemci hangisini kastettiğinizi anlayamaz. Hem ilk argüman hem de api_key: olarak geçirilen bir anahtar da aynı nedenle reddedilir.
Bir oturum çerezi, bir oturum tokenı ya da başka bir hizmete ait bir anahtarBurada yalnızca oe_live_ ve oe_test_ kimlik doğrular ve API de aynısını söyler. Denetim yalnızca önekle ilgilidir; bu yüzden iptal edilmiş bir anahtar yine de istek sunucuya ulaştığında OpenEmail::AuthenticationError olarak başarısız olur.
http ya da https URL'si olmayan veya içinde kullanıcı adı ya da parola bulunan bir base_url:Başka hiçbir şeye ulaşılamaz ve kimlik bilgisinin yeri URL değil, api_key: ya da access_token: alanıdır. İstemci kurulurken fırlatılır.
Bu makinede olmayan bir konağa düz http üzerinden gönderilen bir kimlik bilgisiHiçbir şey gönderilmeden önce çağrı tarafından fırlatılır. https kullanan bir temel URL kullanın.
Saniye cinsinden bir sayı olmayan ya da negatif olan bir timeout:Saniye geçirin ya da zaman aşımı istemiyorsanız 0 geçirin. İstemci kurulurken fırlatılır.
HTTP belirteci (token) olmayan bir başlık adı ya da bir başlık değerindeki satır sonuheaders:, user_agent: ve idempotency_key: içinde denetlenir, çünkü bir satır sonu ikinci bir başlık başlatır.
Herhangi bir metotta boş veya tamamı noktadan oluşan bir idMetot çağrıldığında fırlatılır. Noktalardan oluşan bir yol parçası her URL ayrıştırıcısı tarafından kaldırılır; dolayısıyla istek başka bir uç noktaya ulaşırdı. Geçerli UTF-8 olmayan bir kimlik de reddedilir.
Hash olmayan bir istek gövdesiAnahtar kelime argümanları ya da tek bir Hash geçirin. to_hash çağrısına yanıt veren her nesne Hash sayılır.

test_mode: diye bir seçenek yoktur ve olmayacaktır. Anahtar şeması bir ipucu değil, kimlik bilgisinin bir parçasıdır; dolayısıyla mod anahtarın bir özelliğidir. client.mode öneki ("live" ya da "test") okur ve hiçbir şeye karar vermez.

Tek istemci, birkaç anahtar

İstemciyi bir kez kurun ve paylaşın. Her istek için yeni bir istemci, açık bağlantılarını boş yere atar ve üzerindeki durumun hiçbir kısmı çağırana özgü değildir. İstemci kurulduktan sonra dondurulur ve aynı anda birçok iş parçacığından güvenle kullanılabilir; bu yüzden bir Puma ya da Sidekiq sürecinin yalnızca bir istemciye ihtiyacı vardır ve bir fork'tan sonra alt süreç kendi bağlantılarını açar.

Birkaç çalışma alanı adına gönderim yapan bir iş gibi, aksi hâlde anahtar başına bir istemci gerektirecek durumlarda api_key: değerini çağrıda geçirin. O istek için Authorization başlığının yerini alır ve istemcide arkasında hiçbir iz bırakmaz.

per_call_key.rb
message = {from: "[email protected]", to: "[email protected]", subject: "Your invoice", text: "Attached."}workspace_key = ENV.fetch("OPENEMAIL_API_KEY") client.emails.send(message) client.emails.send(message, api_key: workspace_key) client.threads.list(folder: "inbox", api_key: workspace_key)client.webhooks.list(api_key: workspace_key)

temp_mail dışındaki her metot bunu bir listedeki filtrelerin yanında anahtar kelime argümanı olarak alır; temp_mail metotları ise bunun yerine inbox_token: alır. İstek gönderilmeden önce istemcinin kullandığı kuralla denetlenir; bu yüzden bir yazım hatası, sonradan gidip bulmanız gereken bir kimlik bilgisiyle ilgili bir 401 yerine, bu çağrıya geçirilen api_key hakkında bir ArgumentError fırlatır. Yeniden denenen bir çağrı kendisine verilen anahtarı korur.

client.mode, istemcinin hangi anahtarla KURULDUĞUNU açıklar ve geçersiz kılmayı izlemez. Tek bir istemci birkaç anahtara hizmet ettiğinde bildirilecek tek bir mod yoktur; bu yüzden modu geçirdiğiniz anahtardan okuyun. client.inspect modu ve temel URL'yi gösterir, anahtarı asla göstermez.

Hiçbir metodun sarmadığı uç noktalar

client.raw, her metodun içinden geçtiği taşıma katmanıdır. client.raw.request, henüz hiçbir metodun sarmadığı bir yolu istemcinin kimlik bilgisi, temel URL'si, zaman aşımı ve yeniden deneme politikası uygulanmış olarak çağırır ve ayrıştırılmış gövdeyi bir metodun yaptığı gibi döndürür.

raw_request.rb
ping = client.raw.request("/ping") label = client.raw.request("/labels", method: :post, body: {name: "Invoices"}) p ping[:ok], label[:id]
Anahtar kelimeNe yapar
method:Aksini belirtmedikçe :get. Diğerleri: :post, :put, :patch ya da :delete.
query:Sorgu parametrelerinden oluşan bir Hash. nil ve boş değerler atlanır, bir Array ya da Set virgüllerle birleştirilir ve bir Time, ISO 8601 anı olarak gönderilir.
body:JSON olarak gönderilen bir Hash.
raw: ve content_type:Olduğu gibi gönderilecek baytlar: ikili bir String, bir IO ya da bir Pathname. Bir tür belirtmediğiniz sürece application/octet-stream olarak gönderilir.
accept: ve binary:JSON dışında bir accept: gövdeyi metin olarak döndürür, binary: true ise ikili bir String olarak döndürür.
idempotent: ve idempotency_key:idempotent: true bir Idempotency-Key ekler. Kendi anahtarınızı geçirmezseniz bu anahtar üretilir.
repeatable:Bir hatanın ardından yeniden denenip denenmeyeceği. repeatable: true geçirmediğiniz sürece yalnızca GET yeniden denenir.
api_key: ve timeout:Aynı çağrı başına anahtar ve yalnızca bu çağrı için saniye cinsinden bir zaman aşımı.

Yol tek bir / ile başlamalıdır. Tamamlanmış URL'si temel URL'nin kaynağının (origin) dışına çıkacak bir yol, hiçbir şey gönderilmeden önce ArgumentError fırlatır; böylece kimlik bilgisi asla başka bir konağa ulaşmaz.

Tek kullanımlık gelen kutuları

OpenEmail.create_temp_mail, tek kullanımlık gelen kutuları için hiç API anahtarı taşımayan ve ortamdan da anahtar okumayan bir istemci kurar. Gelen kutularını anonim olarak oluşturur ve her okuma, create çağrısının döndürdüğü gelen kutusu tokenını ya da extend çağrısının döndürdüğü daha yeni tokenı gönderir: ya her çağrıda inbox_token: olarak ya da bir kez OpenEmail.create_temp_mail(inbox_token:) olarak.

temp_mail.rb
temp_mail = OpenEmail.create_temp_mail inbox = temp_mail.createpage = temp_mail.list_messages(inbox[:id], inbox_token: inbox[:token]) p page.items.size, page.expires_at

create_temp_mail, her istemci gibi base_url:, adapter:, max_retries:, timeout:, user_agent:, headers: ve disable_update_notice: alır ve temel URL geçirmediğinizde OPENEMAIL_BASE_URL değerini okur.

OAuth erişim tokenları

Bir kişinin OAuth üzerinden bağladığı, komut satırı aracı ya da ajan gibi bir uygulama, API anahtarı yerine bir erişim tokenı tutar. Onu access_token: olarak geçirin: ya tokenın kendisini ya da call çağrısına yanıt verip tokenı döndüren, lambda veya Method gibi herhangi bir nesneyi. Bu nesne her çağrı için bir kez çağrılır ve o çağrının yeniden denemeleri döndürdüğü değeri yeniden kullanır; bu yüzden tokenın süresi dolmak üzereyken onu bu nesnenin içinde yenileyin, böylece istemciyi hiç yeniden kurmanız gerekmez.

access_token.rb
tokens = {current: "token-from-your-oauth-flow"} oauth_client = OpenEmail::Client.new(access_token: -> { tokens.fetch(:current) }) me = oauth_client.me.get puts me[:clientId], me[:expiresAt] if me[:object] == "oauth_token"
DurumNe olur
api_key: ve access_token: birlikte ya da hiçbiriİstemci kurulurken ArgumentError fırlatır. Hiçbiri yoksa hata iletisi OPENEMAIL_API_KEY ve OPENEMAIL_ACCESS_TOKEN adlarını verir.
Token olmayan bir değerBir token 1 ile 512 karakter arasındadır ve oe_ ile başlamaz; OpenEmail.access_token? bu denetimi yapar. Bu denetimi geçemeyen bir String istemci kurulurken hata fırlatır, böyle bir değer döndüren çağrılabilir bir nesne ise hiçbir şey gönderilmeden önce çağrıdan ArgumentError fırlatır.
OPENEMAIL_ACCESS_TOKENHiçbir kimlik bilgisi geçirmediğinizde ve OPENEMAIL_API_KEY ayarlanmamışsa init, create_client ve paylaşılan istemci tarafından okunur; yani ortamdaki bir anahtar önceliklidir.
Hata fırlatan çağrılabilir bir nesneÇağrı bu hatayı değiştirmeden fırlatır ve hiçbir şey gönderilmez.
Çağrı başına bir api_key:Yalnızca o istek için tokenın yerini alır ve çağrılabilir nesne çağrılmaz.
client.modeToken ile her zaman "live".
OpenEmail.create_temp_mailOrtamda ne olursa olsun hiçbir kimlik bilgisi göndermez.
me.get ve me.pingBir token için get; oauth_token değerinde object, nil olan id ve roleId, bağlı uygulamanın clientId değeri ve kişinin uygulamaya verdiği onayın sona erdiği an olan expiresAt ile yanıt verir. ping; oauth değerinde kind, nil olan keyId ve clientId ile yanıt verir. id ya da keyId okumadan önce object ya da kind değerini kontrol edin.

Bir token bir kişi adına hareket eder ve onun postasını o kişinin okuyabildiği şekilde okur; bu yüzden onu bir anahtar gibi sunucuda tutun.

Doğrulama kodları

Bir alan adını silmek ya da bir webhook'u değiştirmek gibi hassas bir değişiklikten önce API, bir erişim tokenından web uygulamasının kişiden isteyeceği doğrulama kodunu ister. Çağrı, step_up_required? değeri true olan 403'lük bir OpenEmail::PermissionError fırlatır ve hiçbir şey değişmemiştir. Bir kod isteyin, kişinin size verdiği kodu doğrulayın, ardından çağrıyı yeniden yapın. Bir API anahtarından asla kod istenmez.

step_up.rb
domain_id = "b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f" begin  client.domains.delete(domain_id)rescue OpenEmail::ApiError => error  raise unless error.step_up_required?   challenge = client.security.begin_step_up   if challenge[:method] == "email"    puts "Enter the code we emailed to #{challenge[:sentTo]}"  else    puts "Enter the code from your authenticator app, or a backup code"  end   client.security.verify_step_up(code: $stdin.gets.to_s.strip)  client.domains.delete(domain_id)end
MetotNe yapar
security.step_up_statusUygulamanın şu anda doğrulanmış olup olmadığı (elevated, elevatedUntil), sonraki kodun nasıl denetleneceği (method, email ya da totp) ve pencerenin uzunluğu minutes. Hiçbir şey göndermez ve bir duraklamayı bildirmez.
security.begin_step_upBir doğrulama talebi açar. email ile kişinin oturum açtığı adrese altı haneli bir kod gider ve sentTo bu adresi maskelenmiş olarak gösterir. totp ile kişi kodu doğrulayıcı uygulamasından okur ya da bir yedek kod kullanır. Hâlâ açık olan ve deneme hakkı kalan bir talep, resend: true geçirmediğiniz sürece yeniden kullanılır; kilitlenmiş ya da süresi dolmuş bir talep ise sıradan bir çağrıyla değiştirilir. Her uygulama her kişi için saatte 5 ve 24 saatte 20 talep açabilir; bir sonraki 429 step_up_throttled fırlatır.
security.verify_step_up(code:)Kodu denetler ve bu uygulama için hassas değişikliklerin kilidini 60 dakikalığına, yani elevatedUntil anına kadar, hem REST üzerinden hem de aynı değişiklikleri yapan MCP araçları aracılığıyla açar. Bu uygulamadan 24 saat içinde 10 yanlış koddan ya da kişinin tüm uygulamalarından toplam 20 yanlış koddan sonra bu çağrı ve begin_step_up, doğrulamanın ne zaman yeniden açılacağını söyleyen bir iletiyle 429 step_up_locked fırlatır.

İstemci asla kendiliğinden kod istemez ya da çağrıyı tekrarlamaz ve üç metodun hiçbiri otomatik olarak yeniden denenmez, çünkü kaybolan bir yanıttan sonraki yeniden deneme ikinci bir e-posta gönderebilir ya da ikinci bir denemeyi harcayabilir. Kapsam gerektirmezler ve bunlardan birini çağıran bir API anahtarı 400 step_up_not_applicable alır. OpenEmail::STEP_UP_ERROR_CODES bir doğrulamanın başarısız olabileceği her yolu adlandırır ve API hatalar sayfası her biri için ne yapılacağını söyler.

Güncelleme bildirimi

RubyGems'te gem'in daha yeni bir sürümü olduğunda istemci bunu süreç başına bir kez, standart hata çıktısında ℹ openemail 0.0.2 is available, you are on 0.0.1. gibi bir satırla ve ardından gem'in sayfasıyla bildirir. Denetim ilk istemci kurulduğunda, iki saniyelik zaman aşımına sahip bir arka plan iş parçacığında ve yalnızca standart çıktı bir terminal olduğunda çalışır; RubyGems'e ulaşılamaması yok sayılır.

Denetim istemcinin adaptöründen geçer; bu yüzden testler bir terminalde çalıştığında bir test adaptörü RubyGems'e giden bir istek görebilir. Test istemcilerini disable_update_notice: true ile kurun ya da OPENEMAIL_DISABLE_UPDATE_NOTICE değişkenini ayarlayın.

Proxy'ler

Varsayılan adaptör proxy'sini Ruby'nin kendi URI#find_proxy metoduyla bulur; bu yüzden standart kütüphanenin geri kalanıyla aynı kurallara uyar: https_proxy ya da HTTPS_PROXY proxy'yi belirtir, no_proxy ya da NO_PROXY ise doğrudan bağlanılan konakları listeler. Proxy URL'sindeki kullanıcı adı ve parola proxy'ye gönderilir ve bu makinedeki bir sunucuya asla bir proxy üzerinden ulaşılmaz.

Bağlantılar TLS 1.2 veya üzerini kullanır ve sunucunun sertifikasını denetler; bu yüzden TLS'yi inceleyen bir proxy'nin sertifika yetkilisinin makinedeki OpenSSL tarafından güvenilir sayılması gerekir.

Ağ olmadan test etme

adapter: HTTP katmanının yerini alır. Bir lambda da dahil, call(request) çağrısına yanıt veren ve status, headers ve body içeren bir OpenEmail::HttpResponse döndüren herhangi bir nesne olabilir. İstek, method, url, headers, body ve timeout içeren bir OpenEmail::HttpRequest nesnesidir; böylece bir test tam olarak neyin gönderileceğini denetleyebilir.

fake_adapter.rb
requests = [] adapter = lambda do |request|  requests << request  OpenEmail::HttpResponse.new(    status: 200,    headers: {"content-type" => "application/json"},    body: JSON.generate({id: "msg_test", status: "sent", replayed: false})  )end test_client = OpenEmail::Client.new(api_key: "oe_test_fake", adapter:, max_retries: 0, disable_update_notice: true) sent = test_client.emails.send(from: "[email protected]", to: "[email protected]", subject: "Hi", text: "Hello") p sent[:status], requests.first.method, requests.first.url, requests.first.headers["Idempotency-Key"]p requests.first

Bir istek yazdırıldığında Authorization başlığı [redacted] olarak gösterilir; böylece bir test günlüğünde anahtar asla yer almaz.

  • Eşleşen OpenEmail::ApiError alt sınıfını elde etmek için gövde olarak API'nin hata zarfını içeren, 2xx dışında bir durum döndürün; örneğin {"error": {"type": "validation_error", "code": "invalid_parameter", "message": "..."}}.
  • timeout? değeri true olan bir OpenEmail::NetworkError elde etmek için call içinden Timeout::Error ya da onun bir türü olan Net::ReadTimeout fırlatın. Errno::ECONNREFUSED gibi başka herhangi bir StandardError, timeout? değeri false olan bir NetworkError hâline gelir.
  • Adaptörün içinde fırlatılan NameError, TypeError ve ArgumentError, adaptördeki hatalar sayılır. Değiştirilmeden fırlatılırlar ve asla yeniden denenmezler.

Hataları senaryolaştırırken test istemcisini max_retries: 0 ile kurun. Aksi hâlde tekrarlanması güvenli bir çağrıda yeniden denenebilir bir durum ya da bir ağ hatası, aralarında gerçek beklemelerle üç kez denenir.