{"id":5494,"date":"2026-08-30T21:40:37","date_gmt":"2026-08-30T12:40:37","guid":{"rendered":"https:\/\/donguri3.net\/server-tech\/n8n-mercari-reminder-davical-2\/"},"modified":"2026-08-30T21:40:38","modified_gmt":"2026-08-30T12:40:38","slug":"n8n-mercari-reminder-davical","status":"publish","type":"post","link":"https:\/\/donguri3.net\/en\/server-tech\/n8n-automation\/n8n-mercari-reminder-davical\/","title":{"rendered":"Completely Eliminate Forgotten Mercari Shipments! How to Automatically Register Tasks from Gmail to iPhone Reminders Using n8n (with DAViCal Integration)"},"content":{"rendered":"<p>Have you ever received the notification email &#8220;Please ship your item&#8221; when a product sells on Mercari, couldn&#8217;t address it immediately, and ended up nearly forgetting to ship it as it got buried under other emails?<\/p>\n<p>In this article, we built a system using the open-source automation tool &#8220;n8n&#8221; to automatically register tasks in your iPhone Reminders the exact moment this notification email is received.<br \/>\n<span style=\"color: #ff0000;\"><strong><span style=\"text-decoration: underline;\">*This article covers a slightly geeky procedure intended for users who have already built and operated their own CalDAV server such as DAViCal and have completed synchronization settings with their iPhone.<\/span><\/strong><\/span><\/p>\n<h2>Why &#8220;n8n + CalDAV&#8221; Instead of &#8220;.ics URL Subscription&#8221; or &#8220;IFTTT&#8221;?<\/h2>\n<p>When hearing about calendar integration, some might think, &#8220;Can&#8217;t this be done more simply?&#8221; Here, we explain the reasons for intentionally adopting this architecture.<\/p>\n<h3>Reason 1: &#8220;CalDAV&#8221; is Required for Badge Displays in iPhone Reminders<\/h3>\n<p>When hearing about calendar integration, you might wonder, &#8220;Isn&#8217;t it easier to just issue an .ics URL and subscribe to it on the iPhone?&#8221; However, due to iPhone specifications, .ics URL subscriptions can only add events to the standard &#8220;Calendar&#8221; app.<br \/>\nTo manage items as tasks in the &#8220;Reminder&#8221; app\u2014allowing you to check them off as completed or display uncompleted red badges on the app icon\u2014registration via a CalDAV server is strictly necessary.<br \/>\n(Though that sounds like a very logical reason, to be completely honest, the DAViCal calendar server I set up as a hobby years ago has just kept running continuously as part of my home infrastructure, and continuing to use it in that flow is probably the biggest reason!)<\/p>\n<h3>Reason 2: &#8220;Data Extraction Flexibility&#8221; and &#8220;Privacy&#8221; That IFTTT Lacks<\/h3>\n<p>Many might think of &#8220;IFTTT&#8221; as an automatic registration tool for iOS Reminders. IFTTT has a dedicated iOS Reminders integration feature and offers the great advantage of allowing even non-engineers to set it up intuitively.<br \/>\nHowever, there are clear advantages to adopting &#8220;self-hosted n8n&#8221; instead of IFTTT for this requirement.<\/p>\n<ul>\n<li>Complex Data Extraction is Possible: While IFTTT features a simple design connecting provided triggers and actions, it is unsuited for complex text processing and looping tasks like the one here: &#8220;using regular expressions to pinpoint and extract specific product IDs or prices from inside the email body.&#8221; With n8n, advanced data extraction and processing using JavaScript are possible.<\/li>\n<li>Privacy and Operational Costs: Because IFTTT is a cloud service, email contents containing personal purchase information and transaction partner details must be sent to an external server for processing. By combining self-hosted n8n and DAViCal, you can completely secure and complete processing within your local environment (on-premises) without sending personal data to external services. Furthermore, you don&#8217;t need to worry about usage-based pricing or feature limitations based on the number of executions.<\/li>\n<\/ul>\n<h2>Tools Used<\/h2>\n<ul>\n<li>n8n: Workflow automation tool<\/li>\n<li>Gmail: For receiving notifications from Mercari<\/li>\n<li>DAViCal: Open-source CalDAV server (already synchronized with the iPhone Reminders app)<\/li>\n<\/ul>\n<h2>How to Build the Workflow<\/h2>\n<p><a href=\"https:\/\/donguri3.net\/wp-content\/uploads\/2026\/07\/ebd5e45a2a3560dd5261d01c201f0fca.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-3858\" src=\"https:\/\/donguri3.net\/wp-content\/uploads\/2026\/07\/ebd5e45a2a3560dd5261d01c201f0fca.png\" alt=\"Mercari Reminder Flow\" width=\"973\" height=\"118\" srcset=\"https:\/\/donguri3.net\/wp-content\/uploads\/2026\/07\/ebd5e45a2a3560dd5261d01c201f0fca.png 973w, https:\/\/donguri3.net\/wp-content\/uploads\/2026\/07\/ebd5e45a2a3560dd5261d01c201f0fca-300x36.png 300w, https:\/\/donguri3.net\/wp-content\/uploads\/2026\/07\/ebd5e45a2a3560dd5261d01c201f0fca-768x93.png 768w, https:\/\/donguri3.net\/wp-content\/uploads\/2026\/07\/ebd5e45a2a3560dd5261d01c201f0fca-530x64.png 530w, https:\/\/donguri3.net\/wp-content\/uploads\/2026\/07\/ebd5e45a2a3560dd5261d01c201f0fca-565x69.png 565w, https:\/\/donguri3.net\/wp-content\/uploads\/2026\/07\/ebd5e45a2a3560dd5261d01c201f0fca-710x86.png 710w, https:\/\/donguri3.net\/wp-content\/uploads\/2026\/07\/ebd5e45a2a3560dd5261d01c201f0fca-725x88.png 725w\" sizes=\"(max-width: 973px) 100vw, 973px\" \/><\/a><\/p>\n<h3>Step 1: Detect Specific Emails with Gmail Trigger and IF Node<\/h3>\n<p>First, configure the &#8220;Gmail Trigger&#8221; node in n8n. Set the Trigger event to &#8220;Message Received&#8221; and configure it to poll every minute (Every Minute) to retrieve new emails. At this time, make sure to turn off (disable) the &#8220;Simplify&#8221; option in the node settings so that the entire body of the email can be analyzed in subsequent processing.<\/p>\n<p>Next, place an &#8220;IF&#8221; node (or Filter node) to branch out &#8220;only the target emails&#8221; from all retrieved emails. In the condition settings, route emails where the sender (from) is no-reply@mercari.jp and the subject includes \u306e\u767a\u9001\u3092\u304a\u9858\u3044\u3057\u307e\u3059 (Please ship&#8230;) as True to the subsequent process. This design makes the processing paths for &#8220;Mercari emails&#8221; and &#8220;other emails&#8221; visually clear on the workflow and facilitates future expansions.<\/p>\n<h3>Step 2: Extract Data and Create VTODO (Task) Data with Code Node<\/h3>\n<p>Place a &#8220;Code&#8221; node on the True route of the branch and use JavaScript regular expressions to extract product IDs, product names, etc., from the email body. Furthermore, retrieve the email reception date and time (internalDate) and convert it into the YYYYMMDDThhmmssZ format stipulated by the calendar data standard (RFC 5545).<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">const items = $input.all();\nconst results = &#x5B;];\n\nfor (const item of items) {\n    \/\/ Get plain text body (including fallback if field name doesn't exist)\n    const emailBody = item.json.text || item.json.snippet || item.json.html || &quot;&quot;;\n    \n    \/\/ Group extraction using regular expressions\n    const idMatch = emailBody.match(\/\u5546\u54c1ID\\s*:\\s*(&#x5B;a-zA-Z0-9]+)\/);\n    const nameMatch = emailBody.match(\/\u5546\u54c1\u540d\\s*:\\s*(.+)\/);\n    const priceMatch = emailBody.match(\/\u5546\u54c1\u4fa1\u683c\\s*:\\s*(.+)\/);\n    \n    const productId = idMatch ? idMatch&#x5B;1].trim() : `unknown-${Date.now()}`;\n    const productName = nameMatch ? nameMatch&#x5B;1].trim() : &quot;Unknown Product Name&quot;;\n    const productPrice = priceMatch ? priceMatch&#x5B;1].trim() : &quot;Unknown Price&quot;;\n\n    \/\/ Get email receipt date\/time (internalDate) and convert to Date object\n    \/\/ Use current time as fail-safe if unavailable\n    const internalDateMs = item.json.internalDate ? parseInt(item.json.internalDate, 10) : Date.now();\n    const receiveDate = new Date(internalDateMs);\n\n    \/\/ Function to convert to iCalendar standard UTC format (YYYYMMDDThhmmssZ)\n    const formatIcalDate = (dateObj) =&gt; {\n        return dateObj.toISOString().replace(\/&#x5B;-:]\/g, &#039;&#039;).split(&#039;.&#039;)&#x5B;0] + &#039;Z&#039;;\n    };\n\n    const icalDateStr = formatIcalDate(receiveDate);\n    \n    \/\/ Construct VTODO data\n    \/\/ Set receipt date\/time to DUE property to recognize it as a deadline\n    const vtodoStr = \n`BEGIN:VCALENDAR\\\\r\nVERSION:2.0\\\\r\nPRODID:-\/\/n8n Workflow\/\/Mercari Dispatch\/\/JA\\\\r\nBEGIN:VTODO\\\\r\nUID:mercari-${productId}\\\\r\nDTSTAMP:${icalDateStr}\\\\r\nDUE:${icalDateStr}\\\\r\nSUMMARY:\u3010Shipping\u3011${productName}\\\\r\nDESCRIPTION:Please complete the shipping procedure for the Mercari item.\\\n\\\nProduct ID: ${productId}\\\nPrice: ${productPrice}\\\n\\\nLaunch App: https:\/\/mercari.com\/jp\/launch\/\\\\r\nSTATUS:NEEDS-ACTION\\\\r\nPRIORITY:1\\\\r\nEND:VTODO\\\\r\nEND:VCALENDAR`;\n\n    \/\/ Pass extracted variables and generated payload to the next node\n    results.push({\n        json: {\n            productId: productId,\n            productName: productName,\n            productPrice: productPrice,\n            icalData: vtodoStr\n        }\n    });\n}\n\nreturn results;<\/pre>\n<h4>[Important Point for Badge Display]<\/h4>\n<p>When turning on the setting &#8220;Include items due today&#8221; in the iPhone Reminders app, the task must have a &#8220;Due&#8221; date set in order for the uncompleted badge to display on the icon. Therefore, write code that sets the previously converted email receipt date and time to the DUE property of the generated task (VTODO) data.<\/p>\n<h3>Step 3: PUT Tasks to DAViCal via HTTP Request Node<\/h3>\n<p>Finally, register the created VTODO data to the DAViCal server.<br \/>\nUse n8n&#8217;s standard &#8220;HTTP Request&#8221; node and specify PUT as the HTTP method.<\/p>\n<p>The destination URL is a common stumbling block. Sending a PUT request to the parent folder (collection) will result in a 405 Method Not Allowed error. Be sure to send the request by specifying a unique file name (resource URI) at the end, like https:\/\/[host]\/caldav.php\/[user]\/tasks\/mercari-[productID].ics.<br \/>\nAdditionally, because data is sent as plain text rather than JSON, set the Body Content Type to Raw and specify text\/calendar; charset=utf-8 in the header.<\/p>\n<h2>Conclusion<\/h2>\n<p>Since introducing this automation workflow, notifications and badges automatically appear on my iPhone whenever an item sells on Mercari, making shipping task management dramatically easier.<br \/>\nFor those who have a DAViCal server environment, this is a powerful mechanism that can be applied to various use cases, such as e-commerce site notifications or work assignment emails, so please give it a try!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Have you ever received the notification email &#8220;Please ship your item&#8221; when a product sells on Merc [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":3860,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"en_US","_original_post":"https:\/\/donguri3.net\/?p=3857","footnotes":""},"categories":[1167],"tags":[52,387,290,10,397],"class_list":["post-5494","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-n8n-automation","tag-https","tag-java","tag-json","tag-server","tag-397","en-US"],"_links":{"self":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5494","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/comments?post=5494"}],"version-history":[{"count":1,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5494\/revisions"}],"predecessor-version":[{"id":5497,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5494\/revisions\/5497"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/media\/3860"}],"wp:attachment":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/media?parent=5494"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/categories?post=5494"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/tags?post=5494"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}