Class: Cloudflare::Email::WorkerDeployer
- Inherits:
-
Object
- Object
- Cloudflare::Email::WorkerDeployer
- Defined in:
- lib/cloudflare/email/worker_deployer.rb
Overview
Deploys and manages the shipped Cloudflare Email Worker via the Cloudflare API directly — no wrangler, no Node, no npm required.
Required API token scopes:
Account → Workers Scripts → Edit
Usage:
deployer = Cloudflare::Email::WorkerDeployer.new(
account_id: ..., api_token: ...,
)
deployer.deploy(script_path: "cloudflare-worker/src/index.js")
deployer.put_secret("INGRESS_SECRET", "...")
deployer.put_secret("RAILS_INGRESS_URL", "https://...")
Constant Summary collapse
- SCRIPT_NAME_PREFIX =
"cloudflare-email-ingress".freeze
- DEFAULT_COMPATIBILITY_DATE =
"2026-04-01".freeze
- API_BASE =
"https://api.cloudflare.com/client/v4".freeze
Instance Attribute Summary collapse
-
#script_name ⇒ Object
readonly
Returns the value of attribute script_name.
Class Method Summary collapse
-
.default_script_name ⇒ Object
Default Worker name includes the current Rails environment so a dev tunnel never stomps on the production Worker’s RAILS_INGRESS_URL.
- .default_script_name_with_env(env) ⇒ Object
Instance Method Summary collapse
-
#delete_script ⇒ Object
Delete the Worker.
-
#delete_secret(name) ⇒ Object
Delete a Worker secret by name.
-
#deploy(script_path: nil, source: nil) ⇒ Object
Uploads/updates the Worker script.
-
#exists? ⇒ Boolean
True if the Worker script already exists.
-
#initialize(account_id:, api_token:, script_name: nil, compatibility_date: DEFAULT_COMPATIBILITY_DATE, api_base: API_BASE) ⇒ WorkerDeployer
constructor
A new instance of WorkerDeployer.
-
#put_secret(name, value) ⇒ Object
Set/update a Worker secret.
Constructor Details
#initialize(account_id:, api_token:, script_name: nil, compatibility_date: DEFAULT_COMPATIBILITY_DATE, api_base: API_BASE) ⇒ WorkerDeployer
Returns a new instance of WorkerDeployer.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/cloudflare/email/worker_deployer.rb', line 40 def initialize(account_id:, api_token:, script_name: nil, compatibility_date: DEFAULT_COMPATIBILITY_DATE, api_base: API_BASE) script_name ||= self.class.default_script_name raise ArgumentError, "account_id is required" if account_id.to_s.empty? raise ArgumentError, "api_token is required" if api_token.to_s.empty? @account_id = account_id @api_token = api_token @script_name = script_name @compatibility_date = compatibility_date @api_base = api_base end |
Instance Attribute Details
#script_name ⇒ Object (readonly)
Returns the value of attribute script_name.
25 26 27 |
# File 'lib/cloudflare/email/worker_deployer.rb', line 25 def script_name @script_name end |
Class Method Details
.default_script_name ⇒ Object
Default Worker name includes the current Rails environment so a dev tunnel never stomps on the production Worker’s RAILS_INGRESS_URL. Override via ‘script_name:` for tests or explicit control.
30 31 32 33 |
# File 'lib/cloudflare/email/worker_deployer.rb', line 30 def self.default_script_name env = defined?(Rails) && Rails.respond_to?(:env) ? Rails.env.to_s : ENV["RAILS_ENV"].to_s default_script_name_with_env(env) end |
.default_script_name_with_env(env) ⇒ Object
35 36 37 38 |
# File 'lib/cloudflare/email/worker_deployer.rb', line 35 def self.default_script_name_with_env(env) env = "production" if env.to_s.empty? "#{SCRIPT_NAME_PREFIX}-#{env}" end |
Instance Method Details
#delete_script ⇒ Object
Delete the Worker. Useful for teardown in tests.
100 101 102 103 104 105 |
# File 'lib/cloudflare/email/worker_deployer.rb', line 100 def delete_script request( method: :delete, path: "/accounts/#{@account_id}/workers/scripts/#{@script_name}", ) end |
#delete_secret(name) ⇒ Object
Delete a Worker secret by name.
83 84 85 86 87 88 |
# File 'lib/cloudflare/email/worker_deployer.rb', line 83 def delete_secret(name) request( method: :delete, path: "/accounts/#{@account_id}/workers/scripts/#{@script_name}/secrets/#{name}", ) end |
#deploy(script_path: nil, source: nil) ⇒ Object
Uploads/updates the Worker script. Accepts either ‘script_path:` (a path to a .js file) or `source:` (the JS source string directly).
57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/cloudflare/email/worker_deployer.rb', line 57 def deploy(script_path: nil, source: nil) source ||= File.read(script_path) if script_path raise ArgumentError, "must pass script_path: or source:" if source.nil? boundary = "----cf-email-#{SecureRandom.hex(16)}" body = build_multipart(boundary, source) request( method: :put, path: "/accounts/#{@account_id}/workers/scripts/#{@script_name}", body: body, content_type: "multipart/form-data; boundary=#{boundary}", ) end |
#exists? ⇒ Boolean
True if the Worker script already exists.
91 92 93 94 95 96 97 |
# File 'lib/cloudflare/email/worker_deployer.rb', line 91 def exists? response = raw_request( method: :get, path: "/accounts/#{@account_id}/workers/scripts/#{@script_name}", ) response.code.to_i == 200 end |
#put_secret(name, value) ⇒ Object
Set/update a Worker secret.
73 74 75 76 77 78 79 80 |
# File 'lib/cloudflare/email/worker_deployer.rb', line 73 def put_secret(name, value) request( method: :put, path: "/accounts/#{@account_id}/workers/scripts/#{@script_name}/secrets", body: JSON.generate({ name: name.to_s, text: value.to_s, type: "secret_text" }), content_type: "application/json", ) end |