This workflow follows the Emailsend → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"nodes": [
{
"name": "On clicking 'execute'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
40,
140
],
"parameters": {},
"typeVersion": 1
},
{
"name": "Every Friday at 11:00 AM",
"type": "n8n-nodes-base.cron",
"position": [
20,
330
],
"parameters": {
"triggerTimes": {
"item": [
{
"hour": 11,
"mode": "everyWeek",
"weekday": "5"
}
]
}
},
"typeVersion": 1
},
{
"name": "Set Subject",
"type": "n8n-nodes-base.set",
"position": [
220,
330
],
"parameters": {
"values": {
"string": [
{
"name": "subject",
"value": "juvenile_literature"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"name": "Retrieve Book Count",
"type": "n8n-nodes-base.httpRequest",
"position": [
420,
330
],
"parameters": {
"url": "=http://openlibrary.org/subjects/{{$json[\"subject\"]}}.json",
"options": {},
"queryParametersUi": {
"parameter": [
{
"name": "limit",
"value": "0"
}
]
}
},
"typeVersion": 1
},
{
"name": "Check Book Count",
"type": "n8n-nodes-base.if",
"position": [
620,
330
],
"parameters": {
"conditions": {
"number": [
{
"value1": "={{$node[\"Retrieve Book Count\"].json[\"work_count\"]}}",
"operation": "larger"
}
]
}
},
"typeVersion": 1
},
{
"name": "Select Random Book",
"type": "n8n-nodes-base.function",
"position": [
820,
330
],
"parameters": {
"functionCode": "var retrieve_book = 0;\nvar book_count = items[0].json.work_count;\n\nretrieve_book = Math.floor(Math.random() * book_count) + 1\n\nitems[0].json.retrieve_book = retrieve_book;\nreturn items;"
},
"typeVersion": 1
},
{
"name": "Retrieve Detailed Book Info",
"type": "n8n-nodes-base.httpRequest",
"position": [
1260,
330
],
"parameters": {
"url": "=http://openlibrary.org.{{$node[\"Retrieve Basic Book Info\"].json[\"works\"][0][\"key\"]}}.json",
"options": {},
"queryParametersUi": {
"parameter": [
{
"name": "limit",
"value": "1"
}
]
}
},
"typeVersion": 1
},
{
"name": "Retrieve Basic Book Info",
"type": "n8n-nodes-base.httpRequest",
"position": [
1040,
330
],
"parameters": {
"url": "=http://openlibrary.org/subjects/{{$json[\"name\"]}}.json",
"options": {},
"queryParametersUi": {
"parameter": [
{
"name": "limit",
"value": "1"
},
{
"name": "offset",
"value": "={{$json[\"retrieve_book\"]}}"
},
{
"name": "detail",
"value": "true"
}
]
}
},
"typeVersion": 1
},
{
"name": "Book Recommendation",
"type": "n8n-nodes-base.set",
"position": [
1830,
330
],
"parameters": {
"values": {
"string": [
{
"name": "msgSubject",
"value": "=Book Recommendation: {{$node[\"Create Author String\"].json[\"title\"]}}"
},
{
"name": "msgBody",
"value": "=<H2><a href=\"{{$node[\"Create Author String\"].json[\"URL\"]}}\">{{$node[\"Create Author String\"].json[\"title\"]}}</a></H2>\n<p><em>By {{$node[\"Create Author String\"].json[\"authors\"]}}</em><br>\n{{$node[\"Create Author String\"].json[\"description\"]}}</p>"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"name": "Filtered Book Info",
"type": "n8n-nodes-base.set",
"position": [
1460,
330
],
"parameters": {
"values": {
"string": [
{
"name": "authors",
"value": "={{$node[\"Retrieve Basic Book Info\"].json[\"works\"][0][\"authors\"]}}"
},
{
"name": "title",
"value": "={{$node[\"Retrieve Basic Book Info\"].json[\"works\"][0][\"title\"]}}"
},
{
"name": "description",
"value": "={{$node[\"Retrieve Detailed Book Info\"].json[\"description\"][\"value\"]}}"
},
{
"name": "URL",
"value": "=https://openlibrary.org{{$node[\"Retrieve Basic Book Info\"].json[\"works\"][0][\"key\"]}}"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"name": "Create Author String",
"type": "n8n-nodes-base.function",
"position": [
1630,
330
],
"parameters": {
"functionCode": "var arrAuthors = items[0].json.authors;\n\nvar arrNames = arrAuthors.map(function(author) {\n return \"<a href=\\\"https://openlibrary.org\" + author['key'] + \"\\\">\" + author['name'] + \"</a>\";\n});\n\nvar names = arrNames.join(\", \");\n\nitems[0].json.authors = names;\n\nreturn items;"
},
"typeVersion": 1
},
{
"name": "Send No Book Email",
"type": "n8n-nodes-base.emailSend",
"position": [
830,
520
],
"parameters": {
"html": "=<p>Unfortunately, there are no books available for the subject of <em>{{$node[\"Check Book Count\"].json[\"name\"]}}</em>. Please update your n8n workflow with a different subject.</p>\n\n<p>A list of all available subjects can be found at <a href=\"https://openlibrary.org/subjects\">the Open Library</a>.</p>",
"options": {},
"subject": "=Book not found in {{$node[\"Check Book Count\"].json[\"name\"]}}",
"toEmail": "john.doe@example.com",
"fromEmail": "john.doe@example.com"
},
"credentials": {
"smtp": "<your credential>"
},
"typeVersion": 1
},
{
"name": "Send Book Email",
"type": "n8n-nodes-base.emailSend",
"position": [
2030,
330
],
"parameters": {
"html": "={{$node[\"Book Recommendation\"].json[\"msgBody\"]}}",
"options": {},
"subject": "={{$node[\"Book Recommendation\"].json[\"msgSubject\"]}}",
"toEmail": "john.doe@example.com",
"fromEmail": "john.doe@example.com"
},
"credentials": {
"smtp": "<your credential>"
},
"typeVersion": 1
}
],
"connections": {
"Set Subject": {
"main": [
[
{
"node": "Retrieve Book Count",
"type": "main",
"index": 0
}
]
]
},
"Check Book Count": {
"main": [
[
{
"node": "Select Random Book",
"type": "main",
"index": 0
}
],
[
{
"node": "Send No Book Email",
"type": "main",
"index": 0
}
]
]
},
"Filtered Book Info": {
"main": [
[
{
"node": "Create Author String",
"type": "main",
"index": 0
}
]
]
},
"Select Random Book": {
"main": [
[
{
"node": "Retrieve Basic Book Info",
"type": "main",
"index": 0
}
]
]
},
"Book Recommendation": {
"main": [
[
{
"node": "Send Book Email",
"type": "main",
"index": 0
}
]
]
},
"Retrieve Book Count": {
"main": [
[
{
"node": "Check Book Count",
"type": "main",
"index": 0
}
]
]
},
"Create Author String": {
"main": [
[
{
"node": "Book Recommendation",
"type": "main",
"index": 0
}
]
]
},
"On clicking 'execute'": {
"main": [
[
{
"node": "Set Subject",
"type": "main",
"index": 0
}
]
]
},
"Every Friday at 11:00 AM": {
"main": [
[
{
"node": "Set Subject",
"type": "main",
"index": 0
}
]
]
},
"Retrieve Basic Book Info": {
"main": [
[
{
"node": "Retrieve Detailed Book Info",
"type": "main",
"index": 0
}
]
]
},
"Retrieve Detailed Book Info": {
"main": [
[
{
"node": "Filtered Book Info",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
smtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
Discover fresh book recommendations tailored to your tastes without endless browsing, saving hours each week on finding your next read. This workflow suits avid readers or book club enthusiasts who crave personalised suggestions delivered straight to their inbox. It kicks off every Friday at 11:00 AM via a cron trigger, fetches a random book from a preferred source using HTTP requests, gathers key details like summaries and reviews, and sends a curated email with the recommendation.
Use this when you want automated, weekly nudges to expand your reading list, especially if you favour genres like fiction or non-fiction from specific APIs. Avoid it for real-time queries or if you need advanced AI matching based on past reads, as it relies on simple random selection. Common variations include adjusting the cron schedule for daily tips or integrating with Goodreads for more targeted fetches.
About this workflow
Find A New Book Recommendations. Uses manualTrigger, httpRequest, emailSend. Event-driven trigger; 13 nodes.
Source: https://github.com/Zie619/n8n-workflows — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Markdown Report Generation. Uses manualTrigger, itemLists, markdown, emailSend. Event-driven trigger; 10 nodes.
Kv Cloudflare Key Value Database Full Api Integration Workflow. Uses stickyNote, httpRequest, manualTrigger. Event-driven trigger; 47 nodes.
Reputation Engine — Site Refresh. Uses httpRequest, executeWorkflowTrigger. Event-driven trigger; 35 nodes.
Reputation Engine — Content Generator. Uses httpRequest. Event-driven trigger; 30 nodes.
SwitchSubTask. Uses graphql, n8n-nodes-switch-nine-thousand, executeWorkflowTrigger, emailSend. Event-driven trigger; 30 nodes.