Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LoftBox Ruby SDK

AI 에이전트를 위한 이메일 인프라 SDK. 런타임 의존성 없음 — Ruby 표준 라이브러리(net/http·json)만 사용합니다. Rails 통합(railtie + initializer 생성기)을 포함합니다.

요구 Ruby: 3.0 이상.

설치

gem install loftbox

또는 Gemfile:

gem "loftbox"

빠른 시작 (plain Ruby)

require "loftbox"

client = LoftBox::Client.new(api_key: "lb_live_xxx")

# 에이전트 + 메일박스
agent   = client.agents.create(name: "Support Bot", slug: "support-bot")
mailbox = client.mailboxes.create(agent.id, local_part: "support")

# 발송 (멱등 키로 중복 방지)
msg = client.messages.send(
  mailbox_id: mailbox.id,
  to: ["recipient@example.com"],
  subject: "Hello",
  body_text: "World",
  idempotency_key: "welcome-42"
)

# 수신 폴링 → ack
inbox = client.mailboxes.list_inbox(mailbox.id)
client.mailboxes.ack_inbox(mailbox.id, inbox.data.map(&:id))

응답은 가벼운 객체입니다(msg.id, msg.status …). 서버가 새 필드를 추가해도 깨지지 않으며, msg["새필드"] 또는 msg.raw 로 원본 해시에 접근할 수 있습니다.

빠른 시작 (Rails)

initializer 를 생성합니다:

rails generate loftbox:install

config/initializers/loftbox.rb:

LoftBox.configure do |config|
  config.api_key = ENV["LOFTBOX_API_KEY"]
  # config.base_url = "https://api.loftbox.net"
  # config.timeout  = 30
end

이후 어디서든 메모이즈된 전역 클라이언트를 씁니다:

LoftBox.client.messages.send(
  mailbox_id: "mb_xxx",
  to: ["recipient@example.com"],
  subject: "Hello",
  body_text: "World"
)

Rails 의존성은 gem 의 런타임 의존성에 포함되지 않습니다. railtie 는 Rails::Railtie 가 정의된 환경에서만 로드되므로 non-Rails 사용자에게 영향이 없습니다.

설정

LoftBox::Client.new(
  api_key:  "lb_live_xxx",            # 필수
  base_url: "https://api.loftbox.net", # 기본값
  timeout:  30,                        # 초, 기본 30
  http:     nil                        # 선택: 커스텀 HTTP 어댑터(테스트/프록시)
)

인바운드 안전 (#369 인젝션 신호 + #370 발신자 규칙)

수신 메일은 임의 외부 발신자가 보낸 untrusted 입력입니다. 두 가지 통제를 제공합니다.

#369 — 프롬프트-인젝션 신호 (차단 아님)

수신 메시지마다 휴리스틱 점수(injection_score, 0~1)와 발화 카테고리(injection_categories)가 붙습니다. LoftBox 는 차단하지 않으며, 에이전트가 판단합니다.

inbox = client.mailboxes.list_inbox("mb_xxx")
inbox.data.each do |msg|
  if msg.injection_score && msg.injection_score >= 0.7
    # 예: 사람 승인 후에만 메일 내 지시를 따른다.
    warn "의심 메일 #{msg.id}: #{msg.injection_categories&.join(', ')}"
  end
end

#370 — 발신자 allow/block 규칙

발신자 리스트로 수신 자체를 통제합니다(SMTP 거부). allow 리스트가 하나라도 있으면 미매치 발신자는 거부됩니다(화이트리스트). mailbox_id 를 생략하면 org 전체에 적용됩니다.

client.inbound_rules.create(rule_type: "block", pattern_type: "domain", pattern: "evil.com")
client.inbound_rules.create(
  rule_type: "allow", pattern_type: "address",
  pattern: "partner@trusted.com", mailbox_id: "mb_xxx"
)

rules = client.inbound_rules.list(mailbox_id: "mb_xxx")
client.inbound_rules.remove("rule_id")

오류 처리

모든 API 에러는 LoftBox::Error 의 서브클래스이며 status_code / body / request_id 를 노출합니다.

begin
  client.messages.send(mailbox_id: "mb", to: ["a@b.com"], subject: "Hi")
rescue LoftBox::RateLimitError => e
  sleep(e.retry_after_secs) if e.retry_after_secs
rescue LoftBox::NotFoundError => e
  warn "#{e.status_code} #{e.message} (request=#{e.request_id})"
rescue LoftBox::Error => e
  warn "loftbox error: #{e.message}"
end

매핑: 400/422 → ValidationError, 401 → AuthenticationError, 403 → PermissionError, 404 → NotFoundError, 409 → ConflictError, 429 → RateLimitError(retry_after_secs), 그 외 → LoftBox::Error.

페이지네이션

목록 메서드는 LoftBox::Page 를 반환합니다(data 배열 + next_cursor). Enumerable 이므로 바로 순회할 수 있습니다.

page = client.messages.list(mailbox_id: mb.id, limit: 50)
loop do
  page.data.each { |m| process(m) }
  break unless page.next_cursor

  page = client.messages.list(mailbox_id: mb.id, limit: 50, cursor: page.next_cursor)
end

리소스

auth, agents, mailboxes, messages, threads, webhooks, domains, suppressions, inbound_rules(#370), attachments.

예제

examples/quickstart.rb, examples/inbound_safety.rb, examples/rails_usage.rb.

개발

bundle install
rake test       # minitest + webmock
rubocop         # 정적 검사

라이선스

MIT

About

LoftBox Ruby SDK + Rails 통합 — AI 에이전트용 이메일 인프라 (gem: loftbox)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages