You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+66-38
Original file line number
Diff line number
Diff line change
@@ -6,36 +6,47 @@ This solution will hook into your blog creation process and automatically cross-
6
6
7
7
Deploy into your AWS account and type away!
8
8
9
-
For a full summary of this solution [please refer to this blog post](https://www.readysetcloud.io/blog/allen.helton/how-i-built-a-serverless-automation-to-cross-post-my-blogs/) by [Allen Helton](https://twitter.com/allenheltondev).
9
+
For a full summary of this solution [please refer to this blog post](https://www.readysetcloud.io/blog/allen.helton/how-i-built-a-serverless-automation-to-cross-post-my-blogs/) by [Allen Helton](https://twitter.com/allenheltondev)
10
+
and the [CDK-ification of it here](https://matt.martz.codes/improving-a-serverless-app-to-cross-post-blogs) by [Matt Martz](https://awscommunity.social/@martzcodes).
10
11
11
12
## Prerequisites
12
13
13
14
For cross-posts to work successfully, there are a few prereqs that must be met in your setup.
14
15
15
16
* Your blog post must be written in [markdown](https://en.wikipedia.org/wiki/Markdown).
16
17
* Content is checked into a repository in GitHub
17
-
* You have an application in [AWS Amplify](https://aws.amazon.com/amplify/) that has a runnable CI pipeline
18
18
* Blog posts have front matter in the format outlined in the [Blog Metadata](#blog-metadata) section
19
19
20
+
Optionally, you can also publish via an application in [AWS Amplify](https://aws.amazon.com/amplify/) that has a runnable CI pipeline
21
+
20
22
*Note - it is highly recommended you host your blog on your own site. This guarantees you own your content and prevents accidental loss if your favorite platform goes down or has an incident. It also enables [easy canonification](https://support.google.com/webmasters/answer/10347851) of your content when it is cross posted so it ranks higher in search engine results. For a step by step guide on hosting your own blog for free, please [reference this post](https://www.readysetcloud.io/blog/allen.helton/how-to-build-your-blog-with-aws-and-hugo/).*
21
23
22
24
## How It Works
23
25
24
-

26
+

25
27
26
28
The cross posting process is outlined below.
27
29
28
30
1. Completed blog post written in markdown is committed to main branch
29
-
2. AWS Amplify CI pipeline picks up changes and runs build
30
-
3. On success, Amplify publishes a `Amplify Deployment Status Change` event to EventBridge, triggering a Lambda function deployed in this stack
31
-
4. The function uses your GitHub PAT to identify and load the blog post content and pass it into a Step Function workflow
32
-
5. The workflow will do an idempotency check, and if it's ok to continue will transform and publish to Medium, Hashnode, and Dev.to in parallel
33
-
6. After publish is complete, the workflow checks if there were any failures.
31
+
2. Either Amplify's Event or a GitHub webhook triggers a lambda to identify content
32
+
3. The function uses your GitHub PAT to identify and load the blog post content and pass it into a Step Function workflow
33
+
4. The workflow will do an idempotency check, and if it's ok to continue will transform and publish to Medium, Hashnode, and Dev.to in parallel
34
+
5. After publish is complete, the workflow checks if there were any failures.
34
35
* If there was a failure, it sends an email with a link to the execution for debugging
35
36
* On success, it sends an email with links to the published content and updates the idempotency record and article catalog
36
37
37
38
*Note - If you do not provide a SendGrid API key, you will not receive email status updates*
38
39
40
+
### Without Amplify
41
+
42
+
For Step 2 above (Without Amplify), the content-identification lambda creates a function URL. This function URL is added to the GitHub Repo where the blog content lives as a webhook. On push events to the repo the lambda is triggered and it uses a Personal Access Token to fetch files from the repo and detect / upload content to S3.
43
+
44
+
### With Amplify
45
+
46
+

47
+
48
+
For Step 2 above (With Amplify), the AWS Amplify CI pipeline picks up changes and runs build. On success, Amplify publishes a `Amplify Deployment Status Change` event to EventBridge, triggering a Lambda function deployed in this stack
49
+
39
50
## Platforms
40
51
41
52
This solution will take content you create and automatically cross-post it on three platforms:
@@ -50,38 +61,44 @@ Optionally, you can publish straight to publications on each of the platforms. I
50
61
51
62
## Deployment
52
63
53
-
The solution is built using AWS SAM. To deploy the resources into the cloud you must install the [SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html).
64
+
The solution is built using AWS CDK. Get ready by copying `./config/default.json` to `./config/local.json` and adding in the appropriate fields (and removing ones you dont need).
65
+
66
+
Here is an example:
67
+
68
+
```json
69
+
{
70
+
"cdk": {
71
+
"canonical": "hashnode",
72
+
"commitTimeToleranceMinutes": 0,
73
+
"devTo": {
74
+
"devOrganizationId": "1234"
75
+
},
76
+
"github": {
77
+
"owner": "martzcodes",
78
+
"repo": "blog-crossposts",
79
+
"path": "/"
80
+
},
81
+
"hashnode": {
82
+
"hashnodePublicationId": "asdf1234",
83
+
"hashnodeBlogUrl": "https://matt.martz.codes"
84
+
}
85
+
}
86
+
}
87
+
88
+
```
89
+
90
+
In this example, since there isn't an AWS Amplify blog I chose to use hashnode as my "Original" article source. Articles will first be posted there and then dev.to will set the Canonical URL as being from Hashnode.
54
91
55
-
Once installed, run the following commands in the root folder of the solution.
92
+
Once you have the config done...
56
93
57
94
```bash
58
-
sam build --parallel
59
-
sam deploy --guided
95
+
npm install
96
+
npx cdk deploy
60
97
```
61
98
62
-
This will walk you through deployment, prompting you for all the parameters necessary for proper use. Below are the parameters you must fill out on deploy.
63
-
64
-
|Parameter|Description|Required|
65
-
|---------|-----------|--------|
66
-
|TableName|Name of the DynamoDB table to create|No|
67
-
|GSI1|Name of the GSI on the DDB table|No|
68
-
|GitHubPAT|Personal Access Token to load newsletter content from your repository|Yes|
69
-
|GitHubOwner|The GitHub user name that owns the repository for your content|Yes|
70
-
|GitHubRepo|The repository name that contains your content|Yes|
71
-
|AmplifyProjectId|Identifier of the Amplify project that builds your newsletter|Yes|
72
-
|MediumApiKey|API key used to manipulate data in your Medium account|Yes|
73
-
|MediumPublicationId|Identifier of the publication you wish to submit to on Medium|No|
74
-
|MediumAuthorId|Identifier of your user on Medium|Yes if `MediumPublicationId` is not provided|
75
-
|DevApiKey|API key used to manipulate data in your Dev.to account|Yes|
76
-
|DevOrganizationId|Identifier of the organization you wish to submit to on Dev.to|No|
77
-
|HashnodeApiKey|API key used to manipulate data in your Hashnode account|Yes|
78
-
|HashnodePublicationId|Identifier for your blog publication on Hashnode|Yes|
79
-
|HashnodeBlogUrl|Base url of your blog hosted in Hashnode|Yes|
80
-
|BlogBaseUrl|Vase url of your blog on your personal site|Yes|
81
-
|BlogContentPath|Relative path from the root directory to the blog content folder in your GitHub repo|Yes|
82
-
|SendgridApiKey|Api Key of the SendGrid account that will send the status report when cross-posting is complete|No|
83
-
|NotificationEmail|Email address to notify when cross posting is complete|No|
84
-
|SendgridFromEmail|Email address for SendGrid that sends you the status email|No|
99
+
After the first deploy a Secret called `CrosspostSecrets` will be created in AWS Secrets Manager. Go there in the console and paste in the secrets that you've generated.
100
+
101
+

85
102
86
103
## Notification Emails
87
104
@@ -120,12 +137,18 @@ slug: /my-first-blog
120
137
|-----|-----------|---------|
121
138
|title|Title of the blog issue |Yes|
122
139
|description| Brief summary of article. This shows up on Hashnode and Medium and is used in SEO previews|Yes|
123
-
|image|Link to the hero image for your article|Yes|
140
+
|image|Link to the hero image for your article|No|
124
141
|image_attribution|Any attribution text needed for your hero image|No|
125
142
|categories|Array of categories. This will be used as tags for Dev and Medium|No|
126
143
|tags|Array of tags. Also used as tags for Dev and Medium|No|
127
144
|slug|Relative url of your post. Used in the article catalog|Yes|
128
145
146
+
## Image Uploads to a Public S3 Bucket (GitHub Only)
147
+
148
+
When NOT using Amplify and using private GitHub repos as your article source, the identify-content lambda will automatically parse out `` style image embeds and upload the images to a public S3 bucket. It will also re-write the content to use those public S3-based images.
149
+
150
+
***CORS is not set up for the S3 Bucket... though that could be easily added***
151
+
129
152
## Article Catalog
130
153
131
154
One of the neat features provided by this solution is substituting relative urls for the appropriate urls on a given page. For example, if you use a relative url to link to another blog post you've written on your site, this solution will replace that with the cross-posted version. So Medium articles will always point to Medium articles, Hashnode articles will always point to Hashnode, etc...
@@ -181,12 +204,17 @@ Below are a list of known limitations:
181
204
182
205
* Your content must be written in Markdown with front matter describing the blog post.
183
206
* Content must be hosted in GitHub.
184
-
* You are required to post to Dev.to, Medium, and Hashnode. You cannot pick and choose which platforms you want to use.
185
207
* Only Hugo style Twitter embeds are supported. Embeds for other content will not work.
186
-
* This process is triggered on a successful build of an AWS Amplify project. Other triggers are not supported (but can easily be modified to add them).
208
+
* This process is triggered on a successful build of an AWS Amplify project OR a GitHub Webhook. Other triggers are not supported (but can easily be modified to add them).
187
209
* Notifications are limited to sending emails in SendGrid.
210
+
211
+
### Limitations Addressed via Contributions
212
+
213
+
* You are required to post to Dev.to, Medium, and Hashnode. You cannot pick and choose which platforms you want to use.
214
+
* This process is triggered on a successful build of an AWS Amplify project.
188
215
* The only way to deploy the solution is with AWS SAM.
189
216
217
+
190
218
## Contributions
191
219
192
220
Please feel free to contribute to this project! Bonus points if you can meaningfully address any of the limitations listed above :)
0 commit comments