Class: EasyDocForms::Client
- Inherits:
-
Object
- Object
- EasyDocForms::Client
- Defined in:
- lib/easydocforms/client.rb
Overview
Client for the EasyDocForms Partner API. Thread-safe; standard library only.
client = EasyDocForms::Client.new("edfk_live_...")
client.ping # => { org_id: "...", key_name: "...", scopes: [...] }
All methods return Hashes with symbol keys, shaped exactly like the API's JSON (see https://easydocforms.com/docs/api). API failures raise EasyDocForms::APIError subclasses.
Constant Summary collapse
- USER_AGENT =
"easydocforms-ruby/#{VERSION}"
Instance Method Summary collapse
-
#create_fill_link(template_id:, expires_in_days: nil, max_responses: nil, external_ref: nil) ⇒ Object
Mints a hosted URL where a patient fills the form (scope fill_links:write).
-
#create_import(filename:, blank_form_attestation:, pdf_url: nil, pdf_base64: nil, title: nil) ⇒ Object
Imports a blank PDF (async; scope imports:write).
-
#create_webhook(url:, events: nil) ⇒ Object
Registers a webhook delivery URL (scope webhooks:manage).
-
#delete_webhook(webhook_id) ⇒ Object
Deactivates a subscription (scope webhooks:manage).
-
#download_submission_pdf(submission_id) ⇒ Object
The completed, pixel-exact PDF as a binary string (scope submissions:read).
-
#get_import(import_id) ⇒ Object
Polls an import job (scope imports:write).
-
#get_submission(submission_id) ⇒ Object
A patient submission: structured
:answersplus correlation back to the fill link that produced it (scope submissions:read). -
#get_submission_pdf_link(submission_id) ⇒ Object
A time-limited signed URL (~10 minutes) that downloads the completed PDF without any Authorization header (scope submissions:read) — safe to hand onward without embedding your API key.
-
#initialize(api_key, base_url: DEFAULT_BASE_URL, open_timeout: 10, read_timeout: 60) ⇒ Client
constructor
A new instance of Client.
-
#list_templates ⇒ Object
The organization's active templates, newest first (scope templates:read).
-
#list_webhooks ⇒ Object
Active subscriptions, newest first, without secrets (scope webhooks:manage).
-
#ping ⇒ Object
Proves the key authenticates, names its organization, and echoes its scopes.
-
#test_webhook(webhook_id) ⇒ Object
Synchronously delivers one signed test event so you can verify your receiver end to end (scope webhooks:manage).
-
#wait_for_import(import_id, poll_interval: 5, timeout: 900) ⇒ Object
Polls #get_import until the job reaches a terminal status ("succeeded" or "failed") and returns it — a failed import is returned, not raised.
Constructor Details
#initialize(api_key, base_url: DEFAULT_BASE_URL, open_timeout: 10, read_timeout: 60) ⇒ Client
Returns a new instance of Client.
22 23 24 25 26 27 28 29 |
# File 'lib/easydocforms/client.rb', line 22 def initialize(api_key, base_url: DEFAULT_BASE_URL, open_timeout: 10, read_timeout: 60) raise ArgumentError, "api_key is required" if api_key.to_s.empty? @api_key = api_key @base_url = base_url.sub(%r{/+\z}, "") @open_timeout = open_timeout @read_timeout = read_timeout end |
Instance Method Details
#create_fill_link(template_id:, expires_in_days: nil, max_responses: nil, external_ref: nil) ⇒ Object
Mints a hosted URL where a patient fills the form (scope
fill_links:write). external_ref is an opaque correlation id echoed on
submissions and webhooks — it must never contain PHI.
81 82 83 84 85 86 87 88 |
# File 'lib/easydocforms/client.rb', line 81 def create_fill_link(template_id:, expires_in_days: nil, max_responses: nil, external_ref: nil) request(:post, "/fill-links", body: { template_id: template_id, expires_in_days: expires_in_days, max_responses: max_responses, external_ref: external_ref }) end |
#create_import(filename:, blank_form_attestation:, pdf_url: nil, pdf_base64: nil, title: nil) ⇒ Object
Imports a blank PDF (async; scope imports:write). Supply exactly one of
pdf_url (public HTTPS) or pdf_base64. blank_form_attestation must
be true: you attest the PDF is a blank template with no patient
information (PHI). Returns { import_id:, status: "queued" } immediately;
processing typically takes 1–10 minutes.
42 43 44 45 46 47 48 49 50 |
# File 'lib/easydocforms/client.rb', line 42 def create_import(filename:, blank_form_attestation:, pdf_url: nil, pdf_base64: nil, title: nil) request(:post, "/imports", body: { pdf_url: pdf_url, pdf_base64: pdf_base64, filename: filename, title: title, blank_form_attestation: blank_form_attestation }) end |
#create_webhook(url:, events: nil) ⇒ Object
Registers a webhook delivery URL (scope webhooks:manage). The returned
:secret (whsec_*) is shown exactly once — store it; it verifies the
X-EDF-Signature header (see EasyDocForms::Webhook). events filters
deliveries; nil or empty = all events.
116 117 118 |
# File 'lib/easydocforms/client.rb', line 116 def create_webhook(url:, events: nil) request(:post, "/webhooks", body: { url: url, events: events }) end |
#delete_webhook(webhook_id) ⇒ Object
Deactivates a subscription (scope webhooks:manage).
127 128 129 |
# File 'lib/easydocforms/client.rb', line 127 def delete_webhook(webhook_id) request(:delete, "/webhooks/#{encode(webhook_id)}") end |
#download_submission_pdf(submission_id) ⇒ Object
The completed, pixel-exact PDF as a binary string (scope
submissions:read). Works even while completed_pdf_status is "pending"
(renders on demand — just slower).
99 100 101 |
# File 'lib/easydocforms/client.rb', line 99 def download_submission_pdf(submission_id) request(:get, "/submissions/#{encode(submission_id)}/pdf", raw: true) end |
#get_import(import_id) ⇒ Object
Polls an import job (scope imports:write). Result fields appear when
:status is "succeeded"; :error when "failed".
54 55 56 |
# File 'lib/easydocforms/client.rb', line 54 def get_import(import_id) request(:get, "/imports/#{encode(import_id)}") end |
#get_submission(submission_id) ⇒ Object
A patient submission: structured :answers plus correlation back to the
fill link that produced it (scope submissions:read).
92 93 94 |
# File 'lib/easydocforms/client.rb', line 92 def get_submission(submission_id) request(:get, "/submissions/#{encode(submission_id)}") end |
#get_submission_pdf_link(submission_id) ⇒ Object
A time-limited signed URL (~10 minutes) that downloads the completed PDF without any Authorization header (scope submissions:read) — safe to hand onward without embedding your API key. Raises EasyDocForms::PDFPendingError while the frozen artifact isn't ready; fall back to #download_submission_pdf.
108 109 110 |
# File 'lib/easydocforms/client.rb', line 108 def get_submission_pdf_link(submission_id) request(:get, "/submissions/#{encode(submission_id)}/pdf-link") end |
#list_templates ⇒ Object
The organization's active templates, newest first (scope templates:read). Returns the array of template hashes.
74 75 76 |
# File 'lib/easydocforms/client.rb', line 74 def list_templates request(:get, "/templates").fetch(:templates) end |
#list_webhooks ⇒ Object
Active subscriptions, newest first, without secrets (scope webhooks:manage). Returns the array of webhook hashes.
122 123 124 |
# File 'lib/easydocforms/client.rb', line 122 def list_webhooks request(:get, "/webhooks").fetch(:webhooks) end |
#ping ⇒ Object
Proves the key authenticates, names its organization, and echoes its scopes. Requires no scope.
33 34 35 |
# File 'lib/easydocforms/client.rb', line 33 def ping request(:get, "/ping") end |
#test_webhook(webhook_id) ⇒ Object
Synchronously delivers one signed test event so you can verify your receiver end to end (scope webhooks:manage). Returns { delivered:, status_code: } — delivery failure is reported there, not raised.
135 136 137 |
# File 'lib/easydocforms/client.rb', line 135 def test_webhook(webhook_id) request(:post, "/webhooks/#{encode(webhook_id)}/test") end |
#wait_for_import(import_id, poll_interval: 5, timeout: 900) ⇒ Object
Polls #get_import until the job reaches a terminal status ("succeeded"
or "failed") and returns it — a failed import is returned, not raised.
Raises EasyDocForms::Error after timeout seconds.
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/easydocforms/client.rb', line 61 def wait_for_import(import_id, poll_interval: 5, timeout: 900) deadline = Time.now + timeout loop do import = get_import(import_id) return import if %w[succeeded failed].include?(import[:status]) raise Error, "timed out after #{timeout}s waiting for import #{import_id}" if Time.now >= deadline sleep(poll_interval) end end |