<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>j money</title><description>jmoney&apos;s personal website.</description><link>https://jmoney.world</link><item><title>Why I Started a Bear Blog</title><link>https://jmoney.world/posts/why-i-started-a-bear-blog</link><guid isPermaLink="true">https://jmoney.world/posts/why-i-started-a-bear-blog</guid><pubDate>Tue, 16 Dec 2025 01:10:00 GMT</pubDate><content:encoded>&lt;p&gt;Hello everyone this is my first post on my blog.&lt;/p&gt;
&lt;p&gt;I started this because I think it is a good idea to build things in public.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Someone else might learn something.&lt;/li&gt;
&lt;li&gt;I might learn something from someone else.&lt;/li&gt;
&lt;li&gt;A place for me to put whatever is on my mind.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&apos;s about it!&lt;/p&gt;
&lt;p&gt;Stay tuned chat.&lt;/p&gt;
</content:encoded></item><item><title>A Simple Webring Manager</title><link>https://jmoney.world/posts/my-plan-for-waygates-a-simple-webring-manager</link><guid isPermaLink="true">https://jmoney.world/posts/my-plan-for-waygates-a-simple-webring-manager</guid><pubDate>Wed, 17 Dec 2025 21:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Some friends and I want to create a webring between our blogs, so I wanted to make a simple tool for people to set up webrings. An admin can go in and add the websites, order them, and send out an embed via email. Since I love Wheel of Time, I&apos;m calling this project &quot;waygates&quot;. A waygate will be a webring between websites.&lt;/p&gt;
&lt;p&gt;I&apos;m using Go for this project because I want to learn Go. I know, isn&apos;t that quite riveting?&lt;/p&gt;
&lt;p&gt;I want to keep things simple with a minimal frontend. I&apos;m using Templ with HTML templates. I&apos;m familiar with Blade and Twig files in PHP, so I figured this was a good choice. I&apos;m really pushing the &quot;learning Go&quot; angle for this project. I want to do things that are familiar so my focus is on the language.&lt;/p&gt;
&lt;p&gt;For the backend, I&apos;m using the Gin router. I chose this because my favorite drink is a Gin and Tonic. That was sort of a joke but not really. I chose this because it has good middleware support I can add authorization, and it&apos;s lightweight. There will be basic login credentials here so users can manage their webrings.&lt;/p&gt;
&lt;p&gt;For DB interactions, I&apos;m going to use the &lt;code&gt;database/sql&lt;/code&gt; driver and an &lt;code&gt;sqlite3&lt;/code&gt; database. It&apos;s better not to over complicate things. I can practice my SQL skills, without needing to add any unnecessary overhead.&lt;/p&gt;
&lt;p&gt;Stay tuned chat for more updates.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Github repository is &lt;a href=&quot;https://github.com/Jaidenmagnan/waygates&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>You Don&apos;t Need Project Ideas</title><link>https://jmoney.world/posts/you-dont-need-project-ideas</link><guid isPermaLink="true">https://jmoney.world/posts/you-dont-need-project-ideas</guid><pubDate>Tue, 23 Dec 2025 17:55:31 GMT</pubDate><content:encoded>&lt;p&gt;Every passionate developer has had a moment where they felt motivated and ready to work on a new project. Then told themselves some variation of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;I want to work on a new project but I don&apos;t know what to work on.&quot;&lt;/li&gt;
&lt;li&gt;&quot;I have trouble thinking of something to work on.&quot;&lt;/li&gt;
&lt;li&gt;&quot;What is a good project for new developers?&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a common thought I have had countless times. But the truth is: &lt;strong&gt;the best way to find something to work on is to just start working on something&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;By something, I mean literally anything.&lt;/p&gt;
&lt;p&gt;Here is an example I was young, bored, and felt like doing something. So I was like what if I just Twitch stream myself coding advent of code. Then I started this blog, and now I work on projects, and now I have a backlog that feels like it will never end.&lt;/p&gt;
&lt;p&gt;The moral of the story is the best way to find something to do is to &lt;strong&gt;build momentum&lt;/strong&gt;.&lt;/p&gt;
</content:encoded></item><item><title>The Shadow Rising by Robert Jordan</title><link>https://jmoney.world/posts/book-review-the-shadow-rising</link><guid isPermaLink="true">https://jmoney.world/posts/book-review-the-shadow-rising</guid><pubDate>Tue, 30 Dec 2025 03:10:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;this is a spoiler review&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I just finished Wheel of Time Book 4: The Shadow Rising, By Robert Jordan. This book is generally talked about as the best book in the series.&lt;/p&gt;
&lt;p&gt;This is the first time in the series where we really see &quot;He Who Comes With The Dawn&quot; really tear apart the world. You can see some of the seeds Jordan plants in previous books really come to life here. An obvious example here being the relationship between the Tinkers and the Aiel. The exposure of many of their ideals being the complete opposite to what they once were with Rand&apos;s journey through Rhuidean. I also love Lanfear&apos;s character and am really interested to see how she deals with her love for Lews Therin later on.&lt;/p&gt;
&lt;p&gt;The book was not all perfect, I felt it sort of dragged on in the middle. Lots of chapters with traveling with the Aiel, or Perrin just kind of setting up this fight against the Trollocs. Don&apos;t get me wrong, each of these plot lines finished up well, it just took a long time to get there. I also thought the Rhuidean chapter being told backwards was very confusing, but after a summary and a reread I appreciated it.&lt;/p&gt;
&lt;p&gt;That being said, this series has been great so far. I am mainly looking forward to more with The White Tower and I am waiting to see how Mat&apos;s role expands later on in the series.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rating: 4 stars&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>How I Set Up JWT Authentication for Waygates</title><link>https://jmoney.world/posts/how-i-set-up-jwt-authentication-for-waygates</link><guid isPermaLink="true">https://jmoney.world/posts/how-i-set-up-jwt-authentication-for-waygates</guid><pubDate>Tue, 06 Jan 2026 18:07:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Here is devlog #2 for the waygates project. This is how I setup JWT authentication in Go using Gin. As always &lt;a href=&quot;https://github.com/Jaidenmagnan/waygates&quot;&gt;here&lt;/a&gt; is a link to the repository on Github.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;User authentication consists of three endpoints: &lt;code&gt;/signin&lt;/code&gt;, &lt;code&gt;/signout&lt;/code&gt;, and &lt;code&gt;/signup&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;/signin&lt;/code&gt; endpoint has the following flow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check if the email is in our database and grab the hashed password.&lt;/li&gt;
&lt;li&gt;Hash the password from the request.&lt;/li&gt;
&lt;li&gt;Check if the password from the request matches the password in the database.&lt;/li&gt;
&lt;li&gt;Create a JWT token which stores the user ID and store it in a cookie.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Doing this specifically in Go was not much different than other languages. We manage our cookies, request, and response all through the Gin context as seen here. One part of the language I do like is the way Gin handles custom request objects. We were easily able to verify the email without really adding any additional code and it was quite readable.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;func (h *AuthHandler) Signin(c *gin.Context) {
	// ...
	c.SetSameSite(http.SameSiteLaxMode)
	c.SetCookie(&quot;Authorization&quot;, tokenString, 7*24*60*60, &quot;/&quot;, &quot;&quot;, true, true)
	c.Header(&quot;HX-Redirect&quot;, &quot;/&quot;)
	c.Status(http.StatusOK)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;/signup&lt;/code&gt; endpoint consisted of the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check if the email already exists.&lt;/li&gt;
&lt;li&gt;If not, hash the password and store this user in the database.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With all these database operations I wanted to make a small aside here on how easy it is to query the database with Go. All of my repositories are just wrappers around SQL calls, which means there really is no barrier to entry with this language. Take this function to create the user in the &lt;code&gt;/signup&lt;/code&gt; endpoint. &lt;strong&gt;It&apos;s literally just SQL&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Create a new user in the database.
func (r *UserRepository) Create(user models.CreateUser) (models.User, error) {
	query := &quot;INSERT INTO users (email, username, password) VALUES (?, ?, ?)&quot;
	
	result, err := r.db.Exec(query, user.Email, user.Username, user.Password)
	if err != nil {
		return models.User{}, err
	}

	id, err := result.LastInsertId()
	if err != nil {
		return models.User{}, err
	}


	return models.User{
		ID: int(id),
		Email: user.Email,
		Username: user.Username,
		Password: user.Password,
	}, nil
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;/signout&lt;/code&gt; endpoint clears the JWT token stored in the cookie as shown here:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Signout handles user signout requests by clearing the Authorization cookie.
func (h *AuthHandler) Signout(c *gin.Context) {
	c.SetCookie(&quot;Authorization&quot;, &quot;&quot;, -1, &quot;&quot;, &quot;&quot;, true, true)
	c.Header(&quot;HX-Redirect&quot;, &quot;/signin&quot;)
	c.Status(http.StatusOK)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Significant progress on waygates this time around. So far what I like about Go is how verbose it is and easy to debug. I will have another post soon detailing this, but it makes typical debugging just part of writing the code. The docs for Go have been incredibly helpful and this language reads well.&lt;/p&gt;
</content:encoded></item><item><title>blogkitty: A RSS Feed Manager in Discord</title><link>https://jmoney.world/posts/blogkitty-an-rss-feed-manager-in-discord</link><guid isPermaLink="true">https://jmoney.world/posts/blogkitty-an-rss-feed-manager-in-discord</guid><pubDate>Fri, 09 Jan 2026 16:37:00 GMT</pubDate><content:encoded>&lt;p&gt;Hi! I wanted a way to monitor blogs for members in my Discord server, so I created a bot which will monitor RSS feeds into channels with just one command. You can check out the project &lt;a href=&quot;https://github.com/Jaidenmagnan/blogkitty&quot;&gt;here&lt;/a&gt;!&lt;/p&gt;
&lt;h1&gt;How it Works&lt;/h1&gt;
&lt;p&gt;When you run the &lt;code&gt;/monitor [rss-feed] [channel-name]&lt;/code&gt; command in Discord, the bot will create a channel with that name and stream any updates from &lt;code&gt;rss-feed&lt;/code&gt; into it. To remove the feed you can just delete the channel.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In this article I mostly refer to the feeds being monitored as RSS feeds. However, this works with Atom too!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In my Discord server I have a category called &lt;code&gt;feeds&lt;/code&gt; and use these to monitor any sites I am interested in. This is the bot in action:
&lt;/p&gt;
&lt;p&gt;The logic of the bot is fairly simple and follows this format.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The user will use &lt;code&gt;/monitor&lt;/code&gt; command in Discord:
&lt;ul&gt;
&lt;li&gt;The feed added by the user will be added to the database.&lt;/li&gt;
&lt;li&gt;A channel will be created to monitor the feed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Every 10 minutes a cron will run:
&lt;ul&gt;
&lt;li&gt;Pull the URL of each feed from the DB using &lt;code&gt;gofeed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Compare the most recent GUID of the feed with the one stored in the DB.&lt;/li&gt;
&lt;li&gt;If the GUID has changed, send a link to the new post in the specified channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;Development&lt;/h1&gt;
&lt;p&gt;The bot is written in Go on top of the &lt;a href=&quot;https://github.com/bwmarrin/discordgo&quot;&gt;Discordgo&lt;/a&gt; library, which provides bindings around the Discord API. I found it unnecessarily verbose when interacting with the session. Take this function which will reply to the user after they use a slash command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Replies to the current interaction.
func reply(message string, dg *discordgo.Session, i *discordgo.InteractionCreate) {
	dg.InteractionRespond(i.Interaction, &amp;amp;discordgo.InteractionResponse{
		Type: discordgo.InteractionResponseChannelMessageWithSource,
		Data: &amp;amp;discordgo.InteractionResponseData{
			Content: message,
		},
	})
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&apos;s not all bad, it takes advantage of a lot of the languages benefits by being a very simple library with efficient error handling. It doesn&apos;t do much more than wrap API calls and provide types to the API, which is an intended Go-style design. I don&apos;t think this library is as polished as &lt;a href=&quot;https://discord.js.org/&quot;&gt;discord.js&lt;/a&gt; but it worked well for this small application. In the future, I might create a library to better handle slash commands.&lt;/p&gt;
&lt;p&gt;I used a &lt;code&gt;sqlite&lt;/code&gt; database with &lt;a href=&quot;https://github.com/pressly/goose&quot;&gt;Goose&lt;/a&gt; to manage the migrations. What&apos;s nice about Go is that when querying the database I can just use SQL without an ORM. Here is a simplified example of something used in the code (without all the verbose error handling!).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Update the GUID of a feed to match the latest post.
func UpdateFeed(feed Feed) (Feed, error) {
	query := &quot;UPDATE feeds SET latest_post_guid = ?, discord_channel_id = ?, feed_url = ? WHERE id = ?&quot;
	
	DB.Exec(query, feed.LatestPostGUID, feed.DiscordChannelID, feed.FeedURL, feed.ID)
	
	return feed, nil
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For parsing the feeds I used the &lt;a href=&quot;https://github.com/mmcdole/gofeed&quot;&gt;gofeed&lt;/a&gt; library to grab the link to the most recent post. This is a great library which works with both RSS and Atom feeds:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Gets the latest post for a feed.
func getLatestPost(rssUrl string) (*gofeed.Item, error) {
	fp := gofeed.NewParser()
	feed, _ := fp.ParseURL(rssUrl)
	return feed.Items[0], nil
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;What&apos;s Next&lt;/h1&gt;
&lt;p&gt;In the future I would like to make it so there is a designated &lt;code&gt;feeds&lt;/code&gt; channel where each thread is a different feed. This way the server does not get bloated with channels. This bot was a great way to learn about Go and I am having a lot of fun with the language. Contributions and suggestions are always welcome, and I&apos;d love to hear your thoughts!&lt;/p&gt;
</content:encoded></item><item><title>Go Project Structure and SQL Support</title><link>https://jmoney.world/posts/go-project-structure-and-sql-support</link><guid isPermaLink="true">https://jmoney.world/posts/go-project-structure-and-sql-support</guid><pubDate>Fri, 19 Dec 2025 02:36:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Here is the first devlog for the &lt;code&gt;waygates&lt;/code&gt; project!  With this first post I cover the initial file structure and database setup. As always, &lt;a href=&quot;https://github.com/Jaidenmagnan/waygates&quot;&gt;here&lt;/a&gt; is a link to the project on Github.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I typically struggle with file structure when learning a new language. It&apos;s better to do these types of things right the first time to avoid refactoring later.&lt;/p&gt;
&lt;p&gt;I want to use the repository pattern, where we can think of the flow of our code like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ ENDPOINT ] -&amp;gt; [ CONTROLLER ] -&amp;gt; [ SERVICE ] 
-&amp;gt; [ REPOSITORY ] -&amp;gt; [ DB ACCESS ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I was a lowly PHP intern I thought that this structure overcomplicated things and was unnecessarily verbose.  However, pairing this structure with Dependency Injection really cleans up the project and makes it very easy to read. In case you are not familiar with DI, it is a way to pass our dependencies via the constructor instead of instantiating them in each class.&lt;/p&gt;
&lt;p&gt;Here is the directory structure I am starting with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;components/
db/
handlers/
middleware/
migrations/
models/
repositories/
services/
main.go
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next part was setting up the database. I wanted to do this “the Go way” so I decided not to use an ORM. Instead, I will use Go&apos;s &lt;code&gt;sql&lt;/code&gt; library for queries.&lt;/p&gt;
&lt;p&gt;One thing in particular I had an issue with was making migrations and initializing the table. I am using &lt;code&gt;sqlite&lt;/code&gt; because I don’t think this table will get that big all it will hold is the users, and the waygates.&lt;/p&gt;
&lt;p&gt;For migrations I went with &lt;code&gt;goose&lt;/code&gt; because it has support for &lt;code&gt;sql&lt;/code&gt; migrations.&lt;/p&gt;
&lt;p&gt;Here is the initial users table migration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- +goose Up
CREATE TABLE users (
    id INTEGER PRIMARY KEY UNIQUE,
    email VARCHAR(100) UNIQUE NOT NULL,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- +goose StatementBegin
SELECT &apos;up SQL query&apos;;
-- +goose StatementEnd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Overall, solid first step for the waygates project. I am really liking Go as a language because its unique error checking makes it a lot easier to debug. I also noticed that each library I install is relatively lightweight, and I don&apos;t feel overwhelmed like I would in a language like TypeScript.&lt;/p&gt;
&lt;p&gt;Next will be some updates on user authentication  and htmx.&lt;/p&gt;
</content:encoded></item></channel></rss>