webflow_sync 0.1.0 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +88 -1
- data/Rakefile +3 -0
- data/app/jobs/webflow_sync/initial_sync_job.rb +11 -1
- data/app/jobs/webflow_sync/update_item_job.rb +1 -1
- data/app/services/webflow_sync/api.rb +23 -9
- data/lib/generators/webflow_sync/api_token_flow_generator.rb +55 -0
- data/lib/generators/webflow_sync/templates/api_token/omniauth_webflow.rb.erb +3 -0
- data/lib/generators/webflow_sync/templates/api_token/webflow_callback_controller.rb.erb +8 -0
- data/lib/generators/webflow_sync/templates/webflow_sync.rb +1 -0
- data/lib/tasks/{webflow_sync_tasks.rake → webflow_sync.rake} +0 -0
- data/lib/webflow_sync/configuration.rb +7 -3
- data/lib/webflow_sync/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5541d8efea25526da9e623513853d0b2727c0d473251162cc2db71d729ee3c5
|
4
|
+
data.tar.gz: 45ffc209e988d291a010618debf173530bdecdb1686caf9a23653214265cd300
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e850f8be00f87fe2ebd9ede70cf0adf9d7cceeb0d02cf4b8afafbdb17472915717017e6d8a632562c80dc5acc460cb0cbcb3c655b08c5046cef323800abe7779
|
7
|
+
data.tar.gz: 606363c28363aeaf7cd8f3a27859db3a8d5c0db929af486fc0456b27e5ba1ff917d56180e5152a959c337fdc787b016a20335c11dd4ab3ad64c9fec86ef2f800
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
![
|
1
|
+
[![Build Status](https://github.com/vfonic/webflow_sync/workflows/build/badge.svg)](https://github.com/vfonic/webflow_sync/actions)
|
2
|
+
|
2
3
|
|
3
4
|
# WebflowSync
|
4
5
|
|
@@ -28,6 +29,14 @@ bundle exec rails generate webflow_sync:install
|
|
28
29
|
|
29
30
|
## Usage
|
30
31
|
|
32
|
+
### Generate and set WebFlow API token
|
33
|
+
|
34
|
+
Run API token Rails generator and follow instructions:
|
35
|
+
|
36
|
+
```bash
|
37
|
+
bundle exec rails generate webflow_sync:api_token_flow
|
38
|
+
```
|
39
|
+
|
31
40
|
### Add WebflowSync to models
|
32
41
|
|
33
42
|
For each model that you want to sync to WebFlow, you need to run the collection generator:
|
@@ -53,6 +62,79 @@ For example, for `Article` model:
|
|
53
62
|
|
54
63
|
Your WebFlow collection `slug` should be `"articles"`.
|
55
64
|
|
65
|
+
### Set `webflow_site_id`
|
66
|
+
|
67
|
+
There are couple of ways how you can set the `webflow_site_id` to be used.
|
68
|
+
|
69
|
+
#### Set `webflow_site_id` through configuration
|
70
|
+
|
71
|
+
In `config/initializers/webflow_sync.rb` you can specify `webflow_site_id`:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
WebflowSync.configure do |config|
|
75
|
+
config.webflow_site_id = ENV.fetch('WEBFLOW_SITE_ID')
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
#### Set `webflow_site_id` for each model individually
|
80
|
+
|
81
|
+
You can set `webflow_site_id` per model, or even per record.
|
82
|
+
|
83
|
+
To do this, override the `#webflow_site_id` method provided by `WebflowSync::ItemSync` in your ActiveRecord model.
|
84
|
+
|
85
|
+
For example, you could have `Site` model in your codebase:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
# app/models/site.rb
|
89
|
+
class Site < ApplicationRecord
|
90
|
+
has_many :articles
|
91
|
+
end
|
92
|
+
|
93
|
+
# app/models/article.rb
|
94
|
+
class Article < ApplicationRecord
|
95
|
+
include WebflowSync::ItemSync
|
96
|
+
|
97
|
+
belongs_to :site
|
98
|
+
|
99
|
+
def webflow_site_id
|
100
|
+
self.site.webflow_site_id
|
101
|
+
end
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
### Customize fields to synchronize
|
106
|
+
|
107
|
+
By default, WebflowSync calls `#as_webflow_json` on a record to get the fields that it needs to push to WebFlow. `#as_webflow_json` simply calls `#as_json` in its default implementation. To change this behavior, you can override `#as_json` in your model:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
# app/models/article.rb
|
111
|
+
class Article < ApplicationRecord
|
112
|
+
include WebflowSync::ItemSync
|
113
|
+
|
114
|
+
def as_json
|
115
|
+
{
|
116
|
+
title: self.title.capitalize,
|
117
|
+
slug: self.title.parameterize,
|
118
|
+
published_at: self.created_at,
|
119
|
+
image: self.image_url
|
120
|
+
}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
125
|
+
Or if you already use `#as_json` for some other use-case and cannot modify it, you can also override `#as_webflow_json` method. Here's the default `#as_webflow_json` implementation (you don't need to add this to your model):
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
# app/models/article.rb
|
129
|
+
class Article < ApplicationRecord
|
130
|
+
include WebflowSync::ItemSync
|
131
|
+
|
132
|
+
def as_webflow_json
|
133
|
+
self.as_json
|
134
|
+
end
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
56
138
|
### Run the initial sync
|
57
139
|
|
58
140
|
After setting up which models you want to sync to WebFlow, you can run the initial sync for each of the models:
|
@@ -77,6 +159,11 @@ This gem silently "fails" (does nothing) when `webflow_site_id` or `webflow_item
|
|
77
159
|
|
78
160
|
PRs welcome!
|
79
161
|
|
162
|
+
## Thanks and Credits
|
163
|
+
|
164
|
+
This gem wouldn't be possible without the amazing work of [webflow-ruby](https://github.com/penseo/webflow-ruby) gem. Thank you, @phoet!
|
165
|
+
|
166
|
+
|
80
167
|
## License
|
81
168
|
|
82
169
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
@@ -7,8 +7,18 @@ module WebflowSync
|
|
7
7
|
model_class.where(webflow_item_id: nil).find_each do |record|
|
8
8
|
next if record.webflow_site_id.blank?
|
9
9
|
|
10
|
-
|
10
|
+
client(record.webflow_site_id).create_item(record, collection_slug)
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def client(site_id)
|
17
|
+
if @client&.site_id == site_id
|
18
|
+
@client
|
19
|
+
else
|
20
|
+
@client = WebflowSync::Api.new(site_id)
|
21
|
+
end
|
22
|
+
end
|
13
23
|
end
|
14
24
|
end
|
@@ -7,7 +7,7 @@ module WebflowSync
|
|
7
7
|
record = model_class.find_by(id: id)
|
8
8
|
return if record.blank?
|
9
9
|
return if record.webflow_site_id.blank?
|
10
|
-
return if record.webflow_item_id.blank?
|
10
|
+
return WebflowSync::CreateItemJob.perform_now(collection_slug, id) if record.webflow_item_id.blank?
|
11
11
|
|
12
12
|
WebflowSync::Api.new(record.webflow_site_id).update_item(record, collection_slug)
|
13
13
|
end
|
@@ -8,24 +8,38 @@ module WebflowSync
|
|
8
8
|
@site_id = site_id
|
9
9
|
end
|
10
10
|
|
11
|
-
def create_item(record, collection_slug)
|
11
|
+
def create_item(record, collection_slug) # rubocop:disable Metrics/MethodLength
|
12
12
|
collection = find_webflow_collection(collection_slug)
|
13
|
-
response = client.create_item(
|
13
|
+
response = client.create_item(
|
14
|
+
collection['_id'],
|
15
|
+
record.as_webflow_json.reverse_merge(_archived: false, _draft: false), live: true
|
16
|
+
)
|
14
17
|
|
15
|
-
|
18
|
+
# use update_column to skip callbacks to prevent WebflowSync::ItemSync to kick off
|
19
|
+
if record.update_column(:webflow_item_id, response['_id']) # rubocop:disable Rails/SkipsModelValidations
|
20
|
+
puts "Created #{record.inspect} in #{collection_slug}"
|
21
|
+
response
|
22
|
+
else
|
23
|
+
raise "Failed to store webflow_item_id: '#{response['_id']}' " \
|
24
|
+
"after creating item in WebFlow collection #{record.inspect}"
|
25
|
+
end
|
16
26
|
end
|
17
27
|
|
18
28
|
def update_item(record, collection_slug)
|
19
29
|
collection = find_webflow_collection(collection_slug)
|
20
|
-
client.update_item(
|
30
|
+
response = client.update_item(
|
21
31
|
{ '_cid' => collection['_id'], '_id' => record.webflow_item_id },
|
22
|
-
record.as_webflow_json, live: true
|
32
|
+
record.as_webflow_json.reverse_merge(_archived: false, _draft: false), live: true
|
23
33
|
)
|
34
|
+
puts "Updated #{record.inspect} in #{collection_slug}"
|
35
|
+
response
|
24
36
|
end
|
25
37
|
|
26
38
|
def delete_item(collection_slug, webflow_item_id)
|
27
39
|
collection = find_webflow_collection(collection_slug)
|
28
|
-
client.delete_item({ '_cid' => collection['_id'], '_id' => webflow_item_id })
|
40
|
+
response = client.delete_item({ '_cid' => collection['_id'], '_id' => webflow_item_id })
|
41
|
+
puts "Deleted #{webflow_item_id} from #{collection_slug}"
|
42
|
+
response
|
29
43
|
end
|
30
44
|
|
31
45
|
private
|
@@ -39,10 +53,10 @@ module WebflowSync
|
|
39
53
|
end
|
40
54
|
|
41
55
|
def find_webflow_collection(collection_slug)
|
42
|
-
|
43
|
-
raise "Cannot find collection #{collection_slug} for Webflow site #{site_id}" unless
|
56
|
+
response = collections.find { |collection| collection['slug'] == collection_slug }
|
57
|
+
raise "Cannot find collection #{collection_slug} for Webflow site #{site_id}" unless response
|
44
58
|
|
45
|
-
|
59
|
+
response
|
46
60
|
end
|
47
61
|
end
|
48
62
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators/active_record'
|
4
|
+
|
5
|
+
module WebflowSync
|
6
|
+
module Generators
|
7
|
+
class ApiTokenFlowGenerator < Rails::Generators::Base
|
8
|
+
desc 'Generates Omniauth flow for authenticating WebFlow application to get WebFlow API token'
|
9
|
+
|
10
|
+
source_root File.expand_path('templates/api_token', __dir__)
|
11
|
+
|
12
|
+
def generate
|
13
|
+
gem 'omniauth-webflow'
|
14
|
+
run 'bundle install'
|
15
|
+
template 'webflow_callback_controller.rb.erb', 'app/controllers/webflow_callback_controller.rb'
|
16
|
+
template 'omniauth_webflow.rb.erb', 'config/initializers/omniauth_webflow.rb'
|
17
|
+
route "post '/auth/webflow/callback', to: 'webflow_callback#index'"
|
18
|
+
route "get '/auth/webflow/callback', to: 'webflow_callback#index'"
|
19
|
+
|
20
|
+
puts <<~END_OF_INSTRUCTIONS.indent(4)
|
21
|
+
|
22
|
+
|
23
|
+
We've generated all the files needed to successfully authenticate
|
24
|
+
with WebFlow to get API token.
|
25
|
+
There are couple of steps left to get the token:
|
26
|
+
|
27
|
+
1. Download ngrok: https://ngrok.com/download
|
28
|
+
2. Run `ngrok http 3000`
|
29
|
+
3. Copy the URL that ngrok gives you (something like: https://dd7cc807bf91.ngrok.io)
|
30
|
+
4. Go to: https://webflow.com/dashboard/account/integrations
|
31
|
+
5. Register New Application
|
32
|
+
6. In "Redirect URI" put: https://dd7cc807bf91.ngrok.io/auth/webflow/callback
|
33
|
+
7. Save
|
34
|
+
8. Copy client ID and client secret to ENV variables or add
|
35
|
+
them directly in config/initializers/omniauth_webflow.rb
|
36
|
+
9. Start rails server locally
|
37
|
+
10. Go to https://dd7cc807bf91.ngrok.io/auth/webflow
|
38
|
+
11. Finally authenticate, beware which permissions to give
|
39
|
+
(some are "allow access", some are "restrict access", it's confusing)
|
40
|
+
12. Copy the rendered API token and put it in ENV.fetch('WEBFLOW_API_TOKEN')
|
41
|
+
13. After you've got the API token, you probably don't need
|
42
|
+
the Omniauth WebFlow code so you can remove the code that this
|
43
|
+
generator created from your codebase.
|
44
|
+
It is also a security issue to leave the Omniauth endpoint in your
|
45
|
+
codebase, that has the ability to generate API tokens for your WebFlow
|
46
|
+
account!!!
|
47
|
+
|
48
|
+
Easy.
|
49
|
+
|
50
|
+
|
51
|
+
END_OF_INSTRUCTIONS
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
File without changes
|
@@ -6,7 +6,10 @@ module WebflowSync
|
|
6
6
|
|
7
7
|
def configure
|
8
8
|
self.configuration ||= Configuration.new
|
9
|
-
yield(configuration)
|
9
|
+
yield(self.configuration)
|
10
|
+
|
11
|
+
self.configuration.api_token ||= ENV.fetch('WEBFLOW_API_TOKEN')
|
12
|
+
defined?(self.configuration.skip_webflow_sync) or self.configuration.skip_webflow_sync = !Rails.env.production?
|
10
13
|
end
|
11
14
|
|
12
15
|
private
|
@@ -16,9 +19,10 @@ module WebflowSync
|
|
16
19
|
|
17
20
|
class Configuration
|
18
21
|
attr_accessor :skip_webflow_sync, :webflow_site_id
|
22
|
+
attr_reader :api_token
|
19
23
|
|
20
|
-
def
|
21
|
-
@
|
24
|
+
def api_token=(value)
|
25
|
+
@api_token = Webflow.config.api_token = value
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
data/lib/webflow_sync/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webflow_sync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Viktor
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -139,11 +139,14 @@ files:
|
|
139
139
|
- app/models/concerns/webflow_sync/callbacks.rb
|
140
140
|
- app/models/concerns/webflow_sync/item_sync.rb
|
141
141
|
- app/services/webflow_sync/api.rb
|
142
|
+
- lib/generators/webflow_sync/api_token_flow_generator.rb
|
142
143
|
- lib/generators/webflow_sync/collection_generator.rb
|
143
144
|
- lib/generators/webflow_sync/install_generator.rb
|
145
|
+
- lib/generators/webflow_sync/templates/api_token/omniauth_webflow.rb.erb
|
146
|
+
- lib/generators/webflow_sync/templates/api_token/webflow_callback_controller.rb.erb
|
144
147
|
- lib/generators/webflow_sync/templates/migration.rb.erb
|
145
148
|
- lib/generators/webflow_sync/templates/webflow_sync.rb
|
146
|
-
- lib/tasks/
|
149
|
+
- lib/tasks/webflow_sync.rake
|
147
150
|
- lib/webflow_sync.rb
|
148
151
|
- lib/webflow_sync/configuration.rb
|
149
152
|
- lib/webflow_sync/engine.rb
|