<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[dwnppo]]></title><description><![CDATA[dwnppo]]></description><link>https://blog.dwnppo.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 02:07:44 GMT</lastBuildDate><atom:link href="https://blog.dwnppo.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I Synced Our Class Schedule to Discord]]></title><description><![CDATA[First year of college, and I’m already running late. Is it MATH 1100 or ETHICS? IT Lec or NetSys? I didn’t know—so I built a Discord bot that always would. At first, I made this just for one class, as a simple webhook reminder. But then I thought: wh...]]></description><link>https://blog.dwnppo.dev/how-i-synced-our-class-schedule-to-discord</link><guid isPermaLink="true">https://blog.dwnppo.dev/how-i-synced-our-class-schedule-to-discord</guid><category><![CDATA[discord]]></category><category><![CDATA[webhooks]]></category><category><![CDATA[Google]]></category><category><![CDATA[calendar]]></category><category><![CDATA[google apps script]]></category><category><![CDATA[schedule]]></category><dc:creator><![CDATA[dwnppo]]></dc:creator><pubDate>Tue, 29 Jul 2025 16:15:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1753805453385/5f8c8790-fffe-4717-a9fe-3db15e37b54b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>First year of college, and I’m already running late. Is it MATH 1100 or ETHICS? IT Lec or NetSys? I didn’t know—so I built a Discord bot that always would. At first, I made this just for one class, as a simple webhook reminder. But then I thought: why not extend it to the entire BSIT first year?</p>
<p><strong>The goal was simple:</strong> turn a Google Calendar into an automated Discord reminder system that pings our class before every subject.</p>
<p>I didn’t want it to be some heavy, overengineered bot. So here’s what I actually built:</p>
<ul>
<li><p>A Google Calendar that stores all your schedules</p>
</li>
<li><p>A simple script that:</p>
<ul>
<li><p>Fetches events from that calendar</p>
</li>
<li><p>Checks which ones are coming up</p>
</li>
<li><p>Sends reminders to Discord using a webhook</p>
</li>
</ul>
</li>
</ul>
<p>It runs every 5 minutes using a scheduled task (I’ll show you how). You don’t need a full Discord bot for this—you just need a Webhook URL, a shared calendar, and a script that bridges them.</p>
<p>Here’s the webhook in action, and what you’d be creating.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753804869080/32917368-a266-48a0-bba8-7dafd25671d4.png" alt="Snippet of the Discord Webhook, and what you'd be creating." class="image--center mx-auto" /></p>
<hr />
<h2 id="heading-setting-up-the-calendar-aka-the-most-tedious-part">Setting up the calendar (a.k.a. the most tedious part)</h2>
<p>Let’s start with the most tedious part, adding your schedule to Google Calendar.</p>
<p><strong>Use your school account (Google Workspace) if you can</strong>—it has higher limits for automation later. More on that below.</p>
<ol>
<li><p>Head over to <a target="_blank" href="https://calendar.google.com/calendar/u/0/r">Google Calendar</a>.</p>
</li>
<li><p>Click <em>+ Create</em> → <em>Event.</em></p>
</li>
<li><p>For each subject, fill in the subject code or name, set the correct time and date, and use the <em>Location</em> field for the building or room where the class is held.</p>
</li>
<li><p>Then—and this is important—make sure to set it to <strong>repeat weekly</strong>, unless it’s a one-time session.</p>
</li>
<li><p>Then repeat. And repeat. And repeat. Until you’re done with the schedule—literally or emotionally.</p>
</li>
</ol>
<h2 id="heading-setting-up-the-script">Setting up the script</h2>
<p>Now that your calendar’s filled with every class, room, let’s automate it.</p>
<p>We’ll use <strong>Google Apps Script</strong>, which means:</p>
<ul>
<li><p>No installation needed</p>
</li>
<li><p>Runs in the cloud (no always-on laptop or janky Pi needed)</p>
</li>
<li><p>Works natively with Google Calendar</p>
</li>
<li><p>Sends Discord reminders via a simple webhook</p>
</li>
</ul>
<h3 id="heading-what-youll-need">What you’ll need:</h3>
<ul>
<li><p>A Discord Webhook URL</p>
</li>
<li><p>The <strong>role IDs</strong> you want to ping (not just the names—<a target="_blank" href="https://taskoncommunitys-organization.gitbook.io/entity-hub-for-business-end/function-cooperation/discord-role-invitation/how-to-get-role-id-and-role-name-on-discord">here’s how to get them</a>)</p>
</li>
<li><p>Your class schedule in <strong>Google Calendar</strong>, set to repeat weekly, and the Calendar ID (<a target="_blank" href="https://docs.simplecalendar.io/find-google-calendar-id/">here’s how to get them</a>)</p>
</li>
</ul>
<h3 id="heading-the-script-will">The script will:</h3>
<ul>
<li><p>Fetch events from your calendar</p>
</li>
<li><p>Check which ones are starting soon</p>
</li>
<li><p>Ping the corresponding Discord role with a heads-up</p>
</li>
</ul>
<h3 id="heading-the-script">The script:</h3>
<p>This version supports <strong>multiple blocks or sections</strong> (like 1-1, 1-2, etc.), each with their own calendar and role. I originally made a single-class version, but instead of having multiple instances of the script at multiple accounts, I just created a unified calendar reminder for the entire year.</p>
<blockquote>
<p>⚠️ You'll need each class’s <strong>Google Calendar ID</strong> and their corresponding <strong>Discord role ID</strong> for the mentions to work.</p>
</blockquote>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="16fd7ae4fd1500bd841d612d4c95c89c"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a href="https://gist.github.com/dwnppoalt/16fd7ae4fd1500bd841d612d4c95c89c" class="embed-card">https://gist.github.com/dwnppoalt/16fd7ae4fd1500bd841d612d4c95c89c</a></div><p> </p>
<p>Make sure to save it by pressing <code>Ctrl + S</code>.</p>
<h3 id="heading-setting-up-the-triggers">Setting up the triggers</h3>
<p>Normally, you have to click “Run” everytime you want to run the script, which defeats the entire "<em>automatic</em>” stuff.</p>
<p><strong>Creating the first trigger:</strong></p>
<ul>
<li><p>In the Apps Script editor, click the clock icon on the left panel (this is the <strong>Triggers</strong> tab).</p>
</li>
<li><p>Click <strong>+ Add Trigger</strong>.</p>
</li>
<li><p>For <em>Choose which function to run</em>, select <code>notifyUpcomingClassesToDiscord</code>.</p>
</li>
<li><p>For <em>Select event source</em>, pick <strong>Time-driven</strong>.</p>
</li>
<li><p>Then, choose how often you want the script to run.<br />  I suggest every 5 minutes (under “Minutes timer”) so it catches upcoming classes in time.*</p>
</li>
</ul>
<p>*<strong>Note:</strong> <a target="_blank" href="https://developers.google.com/apps-script/guides/services/quotas">Google Apps Script has a daily quota on how often a script can run</a>. Free accounts get fewer executions per day compared to Workspace (school/org) accounts. If you're running into issues with missed reminders, you might need to either reduce the frequency or use a Workspace account to increase your limits.</p>
<p><strong>Create the second trigger (to reset daily reminders):</strong></p>
<ul>
<li><p>Click <strong>+ Add Trigger</strong> again.</p>
</li>
<li><p>Select <code>clearOldNotifications</code> for <em>Choose which function to run.</em></p>
</li>
<li><p>Pick <strong>Day Timer</strong> for the <em>Select type of time based trigger.</em></p>
</li>
<li><p>Finally, select <strong>Midnight to 1am</strong> on <em>Select time of day.</em></p>
</li>
</ul>
<p>And that’s it: the schedule is on the calendar, the script is wired to the webhook, and your Discord server now knows where you’re supposed to be better than you do. You can let it run quietly in the background, automatically reminding your entire block where to go next. No more “<em>ano’ng subject susunod?</em>” or “<em>nasaan kayo?</em>” in the group chat.</p>
<hr />
<p>If you want to tweak the behavior or fix bugs you might run into, check out the FAQ below:</p>
<h2 id="heading-faq">FAQ</h2>
<p><strong>Q: I want the notification to be 10 minutes before the class instead of 15. How do I change that?</strong><br />Go to this part of the script:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> windowStart = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(now.getTime() + <span class="hljs-number">15</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>);
<span class="hljs-keyword">const</span> windowEnd = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(now.getTime() + <span class="hljs-number">20</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>);
</code></pre>
<p>Change the <code>15</code> and <code>20</code> to whatever window you want. For example:</p>
<ul>
<li><p><code>10</code> and <code>15</code> = checks for events starting in 10 to 15 minutes.</p>
</li>
<li><p><code>20</code> and <code>25</code> = checks for events starting in 20 to 25 minutes.</p>
</li>
</ul>
<p>Just make sure the difference between them is about 5 minutes so it doesn’t spam multiple notifications.</p>
<p><strong>Q: Why does it only send one notification even if the script runs every 5 minutes?</strong><br />That’s on purpose. The script remembers what it already sent <em>per event per day</em>, using <code>ScriptProperties</code>. So no matter how many times it runs, it won't resend the same reminder unless you clear it manually (or wait for it to reset the next day).</p>
<p><strong>Q: Why didn’t it send anything?</strong><br />Here’s a quick checklist:</p>
<ul>
<li><p>Did you put the <strong>correct calendar ID</strong>? (It should look like <a target="_blank" href="mailto:something@group.calendar.google.com"><code>something@group.calendar.google.com</code></a>)</p>
</li>
<li><p>Did you use a working <strong>Discord webhook URL</strong>?</p>
</li>
<li><p>Did you <strong>replace the placeholders</strong> like <code>REPLACE_WITH_ROLE_ID_1_2</code>?</p>
</li>
<li><p>Is the event <strong>actually within 15–20 minutes</strong> of now? (Try testing with a class that starts soon.)</p>
</li>
<li><p>Did you <strong>set up the trigger</strong>?</p>
</li>
</ul>
<p><strong>Q: It says that a class will begin in 15 minutes, but its actually 16-19 minutes away. Why?.</strong></p>
<p>That’s normal. It isn’t looking for classes exactly 15 minutes ahead, it looks for <em>classes within a specific time window,</em> in this case, is <strong>15-20 minutes</strong>. This buffer will keep the messages reliable, but that means that the messages can come a little early.</p>
<p>If you’d like to adjust the time window, please refer to FAQ #1. But <strong>be cautious</strong>—making the time window too small (e.g. exactly 15 minutes, or 14-17 minutes) can miss the classes entirely.</p>
<hr />
<p><strong>Thanks for reading!</strong> This little tool started as something for my class, but if it helps make your semester a little less chaotic too, then it’s already done its job.</p>
]]></content:encoded></item></channel></rss>