EPISODE 1 - The Upsell is the Upsell
60 min 2024-10-12
The Upsell is the Upsell

Kalen kicks off TalkingShop.dev with his pal David Robinson (tech lead at fashion brand Cuyana). They geek out on Shopify tricks—discount functions, metafield wizardry, Google-Sheets hacks—swap app horror stories, and share a few Magento flashbacks. A chill, no-filter dev chat for anyone who loves talking shop.

Chapters

00:00 Introduction: The New Podcast
00:50 Holiday Rush in E-commerce
02:00 Return to Podcasting and Coding Focus
05:00 Stack Overflow Memories00:00 - Introduction: TalkingShop.dev Podcast
00:50 Holiday Rush in E-commerce
02:00 Return to Podcasting and Coding Focus
05:00 Stack Overflow Memories
06:15 AI Tools: Copilot, Claude, and Cursor
07:56 Using Claude AI for Google Sheets Integrations
13:02 Learning and Struggling with Rust, JavaScript, and Shopify CLI for Discount Functions
14:30 Liquid’s Performance and Limitations
18:59 Handling Triggers in Google Sheets and Comparing Google Sheets to PIM Systems
22:15 The Evolution of Shopify Metafields and Sections
24:29 Trust and Quality Gaps in Shopify Apps
27:13 Memories of Magento Bug-a-thon
29:03 Comparing Salesforce Features, Regios Discount App, and Price Books in Shopify
34:51 Struggles with Disabling Shopify Variants
35:25 Using Metafields for Price Logic in Shopify
38:19 Creating a Fulfillment Constraint in Shopify
41:24 Live Chat in Apps: Importance and Auto-pop Annoyances
44:01 Upsell Features and Shopify’s Role in Apps
46:36 Switching Reviews and Wishlist Apps
47:21 Disney World Trip and E-books for Planning
49:39 The Love-Hate Relationship with Apps
50:36 The Anxiety of Choosing the Right Shopify App
52:17 Challenges of Managing a Creative Team
55:50 Shopify Project Management Challenges
59:53 Shopify’s Fast and Reliable Performance

Transcript

[00:00:00] that's another one of those like secret ways to talk shop with someone is just like jumping in one of those chats and being like, Hey, Hey, what's up?
[00:00:07] I don't really have any requests. I just want to see how's it going. Right, right, right. How about that e commerce?
[00:00:20] Hey, what's up. Kalen here. Welcome to the first episode of talking shop.dev. A podcast where we just talk shop with other developers working with Shopify. And in this episode, I sat down with my longtime friend, David Robinson.
[00:00:35] He is the director of technology with a fashion brand called Kyana. We talked about a whole bunch of stuff from functions to Google sheets, integrations, NetSuite stuff. A cool discount app that he's using and a bunch of other stuff. So I hope you enjoy it.
[00:00:55] Kalen: Even though I've been in e commerce forever, I haven't really had like an e commerce, like a black Friday rush for a long time.
[00:01:02] Kalen: I've always been like blissfully like not stressed out by that, like I commerce hero and stuff. But, um, that sounds really
[00:01:11] David: healthy.
[00:01:12] Kalen: I it's it. Well, I think it was, I think it was good, but I think it's going to be a lot gnarly this year, dude. I think it's going to be a little nasty. What about, uh, What about you?
[00:01:23] David: Yeah. It's always a little crazy around this time. We definitely have a lot of gifting and holiday purchasing happening this time of year. So it's always a big ramp up to prepare for. Nice.
[00:01:37] Kalen: Nice. I got to close some windows down, dude, and settle into this, uh, settle into this podcast zone. Get locked in. Get locked in.
[00:01:46] Kalen: Yeah, dude. Get fully locked in. Yeah. Yeah. Dude, thank you for, uh, for taking some time. This is, um, I've been, I've had the weirdest itch to do this for so long, dude.
[00:02:01] David: No, it's always good to talk to you. What was it that, um, What made you decide to add another podcast to the
[00:02:08] Kalen: mix? Like, so I had sort of like, let the podcast thing go, uh, because, um, and, and, and all the video stuff and all the multimedia bull bullshit.
[00:02:22] Kalen: Um, it's funny because I, I was, Kind of wanting to ask my daughter to edit because I'm trying to get my daughter like a job, you know Yeah, and I was like, I can't curse if she edits this so um But um Yeah, like I had really just like I don't even do video for client calls anymore Like I I can't stand it.
[00:02:47] Kalen: Like I just want to be left alone and pretty much code now, but then It just came back. Like, I just kept thinking like, man, it'd be cool to just talk about some of this, you know, some of the day to day stuff. Like, you know, you tweet about it and, you know, there's, but you just, I don't know, you're just talking about it.
[00:03:05] Kalen: It's kind of, kind of cool. And then, and then when I realized, like, like I would be fine if it never got a single view, like, and I, and just, I just, you know, Was able to selfishly have like a cool conversation for myself, which in theory, you should be able to just like call a friend and just have a conversation without recording it.
[00:03:28] Kalen: But in practice, in practice, it just doesn't happen. Like, you know, you can, you can like. Talk to a friend, you know, for like a little bit every once in a while, but if you're like, let's do this again next week at this time, they'll think you're a psycho, you know? So that was, uh, that was kind of how it came to be.
[00:03:53] David: Gotcha. Yeah, I always enjoyed watching your multi multimedia content. It was great to Have your voice out there and like starting conversations on Twitter and stuff was always pretty nice
[00:04:05] Kalen: So
[00:04:06] David: yeah
[00:04:06] Kalen: fringe thinking back about it So horrible, dude I found a video that I was I was searching for I can't remember some specific GraphQL thing and I wasn't finding it in the docs. I googled it and And I find a YouTube video that the title is like exactly what I'm looking for. I'm like, great. I click into it.
[00:04:29] Kalen: It was one of my Mesa videos and I was so goofy in the video, you know, which I, I used to like to have fun with those. And then I'd like. Yeah. You know, cut them heavily and speed them up and stuff. And, you know, and I had fun with them. But then just looking at it as just a person trying to get an answer to a question, I was like, this guy is such a dumbass.
[00:04:57] Kalen: But it was the exact thing I was trying to figure out. So, it was kind of cool.
[00:05:02] David: Yeah, thanks Pat and Caitlin.
[00:05:04] Kalen: Yeah, do you, um, do you use Stack Overflow? Do you remember the Stack Overflow days? Like Stack
[00:05:11] David: Overflow is how I survived when I was working on Magento.
[00:05:16] Kalen: Yeah.
[00:05:17] David: For sure. Yeah.
[00:05:19] Kalen: And you would like contribute, like you would answer some questions from time to time, get some points and stuff, and then Not a ton.
[00:05:26] David: I had, I was like, on Stack Overflow, I got a lot of benefit out of it, and then, at one point, I was like, okay, I, I should contribute, and there was some block, like, you couldn't submit an answer unless you had enough points already, and I was like, that's the dumbest thing. Like, I'm, I'm not going to spend time trying to figure out how to get points before I can answer questions.
[00:05:52] David: That doesn't make any sense to me. Right. Um, yeah, but yeah, these days it's like, as soon as I have, as soon as I have a question or I'm just like, I know that I have something I need to do and I'm, I'm kind of like bored and I don't want to write a bunch of like four loops and stuff. I just ask Claude and he does it for me.
[00:06:11] David: So it's interesting, it's different, like, being a builder these days.
[00:06:15] Kalen: Right, right, it's, it is, um, how, cause I've been using, I was using Copilot, I was using, I'm using Cursor, which I don't know if, I don't, I haven't used Clod directly, um, I don't know if Cursor uses it or not, but how do you use Yeah, I think Cursor defaults to Clod.
[00:06:35] Kalen: Okay, I thought that, I thought I might have seen that somewhere. Uh,
[00:06:37] David: but I tried using Cursor. And the, that's, this is another like, okay, I booted up cursor, opened my code base we have, and maybe this is, uh, like revealing the, the truth of our theme. There's, uh, we're built off of the prestige theme and the way that they have like all the JavaScript is just in this one theme JS file.
[00:07:04] David: And now that's like. 2500 lines or something, probably worse. And. Uh, as soon as I started talking to Claude through cursor, it like, listen to what I said about something very specific that I wanted to change. And then it started at line one, made a huge diff and I was like, okay, I need to undo all of this and go back to the way that I used to do things because I'm not ready for this.
[00:07:31] Kalen: You're like, nope. That's funny. Cause, um, I've used it on, I guess now that you mentioned it, mostly smaller files. And, um, yeah, I've seen some of those long ass theme files and, uh, that's so funny. You're just like, nope, just, yeah, no, thank you. That's so funny. It's
[00:07:56] David: not too bad though, to like ask Claude some specific, a lot of the things that I work with Claude on these days are, um, we started getting into, uh, adding some magic to Google sheets.
[00:08:10] David: We use a lot of. Uh, Google sheets for things.
[00:08:13] Kalen: You know,
[00:08:13] David: um, yeah, you helped me with one. And, uh, so we're doing a lot more of that these days. Like some, uh, bank wrecking silly reconciliation stuff for the finance team. Like it's, it's cool.
[00:08:26] Kalen: Oh, cool.
[00:08:26] David: Uh, that stuff is like progressing through. Nice. The organization.
[00:08:32] David: But yeah, it's a lot of, like, those are always pretty small, like little JavaScript, like two, 300 line things, and Claude just bangs those out.
[00:08:41] Kalen: Mm. Mm hmm. Mm hmm. I think I, I, I actually, I did the same thing recently because, um, I, I was doing, working on a, a Google Sheets app script deal. And, um, and I couldn't remember like the syntax for like getting rows and getting the data within a row and active, like in like an edit trigger is like, I didn't want to have to go.
[00:09:08] Kalen: I remember last time I looked it up, it just took me forever to get it right. So I just asked it and it just nailed it. It was so, so nice. Like a certain percentage of the time it just nails it. And You're like, dude, I would have spent 45 minutes, like I would have figured it out, but I would have spent a good 30 minutes just, you know, messing around with the syntax and going through six different bad websites.
[00:09:34] Kalen: Yeah. Signed examples and stuff.
[00:09:37] David: Especially when you're trying to get started and it's like a blank, blank screen. Like it's, it's way faster to read something that was output and understand it, like whether or not that meets all of your criteria. Then it is to try and just like write it out, test it at least most of the time when you get something from Claude, it works, even though it's not perfect.
[00:10:00] David: And then you just adjust from there. And that's been huge for us.
[00:10:05] Kalen: Yeah. Because so, so much of the time, that's the, that's the, um, thing you're having to work like battle through as a developer is that you're, you're just trying to, Get going and your brain is kind of fighting against you. Like once you're in, once you're into the flow of working on something, then it just kind of flows unless you're trying to learn rust yesterday, like an idiot.
[00:10:27] Kalen: How did that go? Okay, dude. Several issues here. Um, one is that, like, I've seen people tweet about Russ, like, you know, it's great, blah, blah, blah, and I see that Shavoy supports it, cool. I finally had a reason, and I don't, I'm not the guy that's out here learning different languages all the time, you know what I mean?
[00:10:48] Kalen: I, like, stick with what I know. And, uh, but I needed to look at it because, uh, I'm doing a, uh, discount function for a B2B use case that could potentially have a bunch of line items. And somebody told me that like on a hundred, hundred and fifty line items, your discount function or your, your functions are, are gonna chew through all the execution limits, just like parsing JSON, like, and especially if there's like a JSON metafield in there or something like that.
[00:11:18] Kalen: So I was like, okay, I got to do, I got to figure out Rust, so I, I cracked it open. The code looks ridiculous, dude. The syntax, I mean, it's like, have you ever looked at Objective C? Like the syntax just looks so weird, and Yeah,
[00:11:32] David: does, does Rust have like reference notation and stuff like that you have to work with?
[00:11:37] Kalen: I, I, I think, um, I think it does. It has like probably types. It just looks so different to me. And then, um, and then I was getting cursor to write some stuff and, and it was writing some stuff and I was like, for starters, or let me just log something to the console, like that can't be too hard. And then it, uh, it like imported it.
[00:12:02] Kalen: It was, it was interpreting the log as a output. And then it was saying that the output format was invalid, so I'm like, it didn't even, um, and then on top of that, I realized today that, uh, my Shopify app dev CLI was not picking up the changes I made. In code, it was running the previous version that I had deployed, um, of the function.
[00:12:33] Kalen: So like, I finally, it took me like a while to realize that this, like, cause it's like layers and layers of confusion and like the top layer was that none of the changes I was making were even, were even taking effect.
[00:12:50] David: Yeah. That's a big layer.
[00:12:54] Kalen: So, and then today you
[00:12:56] David: have to write, you have to write those functions in Rust.
[00:12:59] David: I thought you could do it in like JavaScript or something.
[00:13:02] Kalen: You can, you can do JavaScript, but it's Rust is a lot more efficient. Um, is what I'm told. So like when, like you're dealing with those execution limits, if you're running up against them, then you could be screwed with JavaScript. But the other thing I saw yesterday is just recently, like September 18th, they, they announced that there's like a 40 percent performance improvement to JavaScript's handling of the input stuff.
[00:13:31] Kalen: Which is pretty cool. And then the other thing that multiple people told me, they were like, honestly, just, um, write it in JavaScript or TypeScript. I can't figure out TypeScript. And yeah, JavaScript is fine. Like, and, um, and they said like, just, just ask, um, AI to translate when you have it working in JavaScript, just ask you how to translate it to rust and multiple people told me they did that, which makes sense.
[00:14:00] Kalen: That seems like the kind of thing I would do a good job of. So maybe I'll, maybe I'll just circle back to it, but I didn't figure out a package and just basic stuff.
[00:14:11] David: Oh, yeah. You should, you should write it in Rust and in JavaScript and see if it actually has any impact.
[00:14:18] Kalen: Yeah, no, I'm not that guy, dude. I'm not that guy, David.
[00:14:22] Kalen: I don't, I really don't care enough. Well, I'm
[00:14:25] David: lazy, so I would just like, I'm just doing this in JavaScript. Yeah,
[00:14:30] Kalen: um
[00:14:31] David: It does, uh, it does remind you, like, the, the convenience that you get. And liquid with some of the limitations there. Um, like, I don't know how much you deal with liquid stuff. Um, but there are some big limitations, like a four loop cannot go more than 50 times.
[00:14:52] David: Right. Um, and so you end up building stuff in a way that deals with that. And I, I think, well, obviously that causes your theme to be more performant because you have to think about it that way, but I guess the same is true for discount functions.
[00:15:09] Kalen: Yeah,
[00:15:10] David: yeah.
[00:15:11] Kalen: Um, yeah, I mean, that's, that's the kind of thing with Shopify is that the, the, um, the limitations are like explicit.
[00:15:17] Kalen: You have zero control over them. And then. And they're, and they're usually for very good reason. And so then you just have to work around it as opposed to like with open source. It's like, you can do everything, anything you want. And then fast forward a few years and every site has a huge load in the loop.
[00:15:34] Kalen: Yeah. What have I
[00:15:35] David: done to myself?
[00:15:36] Kalen: Yeah. Yeah. Actually, my, my, my buddy, Eric, uh, did a whole podcast, um, for a Magento back a couple of years ago called load in the loop and they, they, they, Yeah, I don't know if you saw that him and Ivan would review sites for performance issues. Yeah. Yeah. Um, but, but, uh, but yeah, dude, like, but liquid is pretty cool, man.
[00:16:03] Kalen: Um, I've been getting more comfortable with it and, um, and I use it in mechanic, which is like a different flavor of liquid. And then I do a little bit of front end stuff. Um, but I really like it actually. I like it a lot.
[00:16:19] David: Yeah, me too.
[00:16:20] Kalen: Yeah. Um, so on the Google Sheets thing, uh, what I was saying was that I had to do, Oh yeah, so, so the last time I had done Apps Script stuff with, um, with a trigger, with an edit trigger was for the stuff you, for your stuff.
[00:16:42] Kalen: And I remember it worked fine. Like it triggered reliably and stuff. And so I'm taking over this project that this developer had not worked out for. And I'm looking at, they have a sheet and they have the app script. And the first time I test it, it triggers a webhook over to gadget and it, and it saves the data.
[00:17:02] Kalen: I'm like, cool. And I'm looking at the runtimes and it's like, every time this thing runs, it's like 30 seconds, 25 seconds. And then it, it errored out a couple of times. And, um, I was like, I, for a second, I thought that I was like, you know what, dude, this app script stuff is probably just not reliable because I mean, it's free.
[00:17:25] Kalen: Like, how can you like, and the spreadsheet had like, I don't know, like, uh, 10, 000 records or something. So I was like, maybe it just doesn't work at this scale. And. Then I took, um, like I told, I basically told them, like, we should do it on Airtable. They're like, no. And then I took another look and the guy, the previous developer, in order to handle, uh, deletes, uh, it, it was every time an, a cell was edited, it was saving the entire sheet to like a hidden sheet, which I didn't know existed.
[00:17:59] Kalen: And then it was using that to compare a Delta on the current state. And it was just super slow.
[00:18:08] David: Yeah. I, I don't know if I've ever used an on edit trigger. Most of the time I try and either do like a, a dropdown menu for someone to just like, Hey, I'm done with the sheet now do the magic. Yeah. And then, uh, more recently I've, I've used like, uh, because that's also a bit of cognitive load for someone who's working in the sheet, they have to like go remember to click this thing up at the top, uh, to give like a kind of an on edit experience, uh, I set up a trigger that's just a time based trigger and, um, And then set like another, in another column, set whether or not that row's been processed.
[00:18:54] David: And then, just as part of the time trigger, it checks for new things and then does stuff.
[00:18:59] Kalen: Oh, that's cool. By the way, can you, can you, uh, query on updated rows when you do that? Can you, Only grab updated rows on, on a, on that kind of a trigger.
[00:19:13] David: No, I, I just, uh, it's like a, like a mutex or whatever nerd word it is, where like, there's just one more column that gets added that says whether or not this one has been touched.
[00:19:26] David: Um, I guess it's a little bit different because in this scenario, each time someone goes into the sheet, there's like new rows for them to process. And so they're going to the new row, selecting some things in a column, and then next time the trigger happens, it just puts a one in the next column over so that it knows, uh, next time to just look at those that don't have ones.
[00:19:48] Kalen: Hmm. Okay. I gotcha. I gotcha. Cause that was the other thing I was looking at was the doing it on an updated, um, thing, but it seems like it's not, it's not possible. Um,
[00:20:00] David: yeah. Plus I, I feel like there might be shenanigans with Google sheets when you like refresh a page or something, or like, um, I know when you go back into a sheet, if you've got functions set in a cell, they'll reprocess.
[00:20:17] David: So I don't know if that. Has any impact.
[00:20:20] Kalen: Right. Right. But it is interesting how, like, a lot of decent sized, like, businesses, like, want to use Google Sheets for some kind of an integration, like, you know. For a while there, Sheets were
[00:20:34] David: evil, do you remember that? Everybody was like,
[00:20:38] everybody was trying to get out of Excel documents.
[00:20:42] David: Like we shouldn't be doing this in a spreadsheet. It should be in a PIM or something like that. Right. It feels like it's going back. Like, let's just use the tools that work.
[00:20:51] Kalen: Yeah. I don't know. I don't know if there's an overall trend going back or not. You probably would. I mean, you may have seen that internally.
[00:20:57] Kalen: Maybe they considered a PIM and then they went, well, you were looking at a PIM if I recall. Yeah. Um, so did you guys basically just say, Hey, we can do it in sheets. Yeah.
[00:21:09] David: That's where we're at right now. I mean, a PIM is just like another thing I have to worry about breaking. And every time I talk to these PIM companies, um, they say that they're deeply integrated with Shopify.
[00:21:23] David: I get excited.
[00:21:25] David: They
[00:21:25] David: say MetaFields, I get even more excited. But then when I go in, it's like, okay, we support MetaFields, but it's only single line text, uh, no product or variant references. And it's just like, okay. So you don't support MetaFields.
[00:21:41] Kalen: You're like, let me talk to you about my collection search results.
[00:21:44] Kalen: Adjacent, adjacent content MetaFields. Oh man,
[00:21:51] David: I feel like I came into Shopify at the perfect time. Like MetaFields were just released. Yeah. And I was, I was already starry eyed about like learning about Shopify. Um, and the metafields were here and my previous assumptions about Shopify were just destroyed by the existence of metafields and then now they drive like a lot of stuff for us.
[00:22:15] Kalen: Yeah, it's funny you mention that, like, coming at just the right time, because I feel kind of like that too. I mean, so many people were in Shopify for so long, and they dealt with things like, like I'll hear about pre 2.
[00:22:26] Kalen: 0 themes and stuff, and I don't get it. Like, I don't, I don't, I don't have any memories of the, that, like, I'm assuming it was, I'm assuming they were bad and like sections I think are really good and metafields and, um, and then flow, like I was thinking before, like, like, uh, I was, I was doing a flow that worked off a schedule trigger.
[00:22:48] Kalen: And like, in order to get it started, you have to like create the flow schedule at some point in the future, like a couple of minutes in the future. Then you have to wait and then you, uh, and then it runs. And then what I do now is I make my changes and I hit a re, I retry the flow to rerun with the new changes.
[00:23:06] Kalen: But I was like, dude, imagine before there was a retry, like people working on scheduled flows and, and actually there didn't even used to be a schedule trigger. I saw a third party app that did schedule triggers for flows. Um, anyway, but yeah, like there's so much cool stuff. And, um, That is like such a, such a big part of your work, you know, that like just doesn't exist before.
[00:23:34] David: And when, when Shopify does it, it's like usually pretty good. So by the time it makes it there and you can use it, it's like, you can feel confident that it is usable and it will work.
[00:23:45] Kalen: Yeah.
[00:23:46] David: Um, but yeah, my, like before, before we went into this replatform to get onto Shopify, my, what I knew about Shopify was, It's limited and your customizability and, um,
[00:24:06] David: like you have to be careful about the apps you install because everyone's installation is just like super crammed with apps and you install something and it breaks everything. And I was like, really scared of that. Now it seems like apps are pretty nice. Like you can install the app, it won't break stuff until you're ready to inject it into your theme.
[00:24:29] Kalen: That's a very broad statement. Okay,
[00:24:34] David: well, if it says built for Shopify, then I won't.
[00:24:38] Kalen: Then I'll install it. Oh dude, I love a built for Shopify app. Definitely. You just immediately have such a higher level of trust.
[00:24:49] David: If you, if your app lives within the Shopify admin Chrome, I trust you 100 percent more.
[00:24:58] Kalen: Yeah.
[00:24:59] Kalen: Especially if the app UI is up to date. Um, But, you know, that's another thing,
[00:25:06] David: like the, the, the, the breadth of quality in apps is still pretty huge. There are apps that are highly rated and everyone uses them. Um, but then when you go in, it just feels like it's not.
[00:25:23] Kalen: Oh, yeah.
[00:25:24] David: It's not new. Like, it doesn't feel good.
[00:25:27] David: Yeah,
[00:25:28] Kalen: that's the simplest way to put it.
[00:25:33] Kalen: It's a lot of apps that just don't feel good, dude.
[00:25:35] David: Yeah. I mean, maybe that's from, uh, from our Magento time, just like, uh, having to feel good about modules. It's like a thing that maybe we both have baggage around. And so,
[00:25:51] Kalen: I mean, I think it's, I think it's universal. Like you want to feel good about the, whether they're apps or modules or plugins or whatever you want, you know, you want any, in any kind of an ecosystem, you have players that are going to be less well integrated than others, you know, some that are kind of slapped together.
[00:26:10] Kalen: Um, I'm going to test your Magento. Memory real quick, because some of my friend just texted me and was asking me about error logging. He was like, Hey, we, we don't, we need an app to do error logging in his Magento instance. And I couldn't even remember. I was like, dude, I can't for the law. I haven't done Magento for like five years, but I felt a little embarrassed that I didn't remember.
[00:26:36] David: Isn't it? Wasn't it? Uh, like there's a, so it's PHP and there is a. I don't remember what it's called, but you can always access the mage object. Wasn't like mage colon, colon log, something like that.
[00:26:53] Kalen: Right. I remember that. Yeah, that's true. But I, but I guess like a, like an error reporting, I feel like there was like an error reporting solution or, uh, Uh, module, whatever that would, like, send out notifications and let you handle it.
[00:27:07] Kalen: Anyways, I'm feeling dirty just talking about Magento this much.
[00:27:13] David: Yeah. It feels wrong. I was thinking about, like, when did, uh, when did I meet Kaelin? And it was, do you remember? Hackathon, right? It was, uh, it wasn't a hackathon. It was a bug a thon. It was a Magento, Magento had just been acquired by eBay, I think.
[00:27:36] David: And for some reason they wanted help, uh, maybe we're still under NDA for this. I don't know, but they, uh, they wanted help from the community, like fixing some of the bugs that people were complaining about. And so they just got like 20 of us or 30 of us in a, in a room with some Magento project managers and developers.
[00:27:57] David: And we met like some of the rockstar devs and old Magento. Anyway, sorry. I'm talking about Magento still Shopify. Bye guys. This is, this is
[00:28:07] Kalen: horrible, but who does a bug a thon? Like the whole point of a hack a thon is that it's like fun. It's like aspirational. It's like, we're going to hang on cool stuff.
[00:28:18] Kalen: And you know, like Shopify wouldn't do that, dude. They wouldn't, first of all, you can't fix Shopify bugs. that's just, that's out of hand. It's uncalled for.
[00:28:28] Kalen: I was trying to think about whether like the way Shopify functions work, where you're deploying code directly to run like natively in the SAS. Um, I was, I was, I was thinking to myself like that doesn't exist anywhere else. And then I was like, who knows, maybe I, I know there's like stored procedures that, you know, like some systems have, I don't know if that would qualify, but.
[00:28:55] Kalen: And I don't know that much about other systems in the first place, but there's like cartridges, I think in Salesforce, but yeah,
[00:29:03] David: Salesforce cartridges.
[00:29:05] Kalen: Yeah.
[00:29:07] David: More good times. So one thing, one good thing I'll say about Salesforce is, um, their, their promotion engine is really good.
[00:29:18] Kalen: Okay.
[00:29:19] David: You can do a lot of really cool pricing stuff.
[00:29:22] David: And like, I have problems with that. Yeah,
[00:29:27] Kalen: right, right,
[00:29:28] David: right. Like there's people on the team who are who are like say things like didn't we used to be able to do this? And um that that stings in my heart when when I hear that but dude working through it
[00:29:41] Kalen: What are let's talk. Let's talk about it, dude. I'm working on a couple couple discount functions as we speak Um, yeah.
[00:29:49] Kalen: What, what's, what's the discount you need to do? We'll get this done live, man.
[00:29:59] David: I regret to inform you, Caitlin, but I, I already found a really good discount app. Maybe you can check it out, but, um, it's, uh, so there's this app, uh, called Regios. And maybe I, maybe I shouldn't, I don't know. And so it, it's, uh, I, I saw this guy on Twitter, Toby, I think is his name. And he was talking about running the, running his business.
[00:30:24] David: And I always thought that was interesting. So I checked out the app and there's one feature that he has. That's super cool. I don't know if you've seen it, but, um, it is, uh, instead of going through a discount. And like checking boxes of like how you want it to work and what it should apply to. Um, there's a logic based discounts.
[00:30:49] David: And so that looks like Shopify flow.
[00:30:53] Kalen: Yeah. I've seen that. It's so cool. I've seen that. It's really
[00:30:56] David: cool. Like specifically there's, um, like if you make a discount in Shopify, you set a particular percent, like 20 percent off, and then you can select a collection. That it applies to with this, uh, with this logic thing, it allows you to do something like for the apparel collection, it should be 20 percent off for the bags collection.
[00:31:22] David: It should be 15 percent off or something like that. Um, and that alone is something that I, I don't think I've seen. Um, when I saw that
[00:31:36] Kalen: app, when I saw the flow style editor for that app, I was like, dude, this is. This is way too good. Um, and, uh, I met, I met, uh, Toby in Toronto. Good dude. Very tall. Oh, cool.
[00:31:50] Kalen: Yeah. Good dude. And all the coolest people are tall. Yeah. . Yeah. Tall guy too. And, um, it's, uh, yeah, I think he's gonna kill it, dude. Sometimes I'll think to myself like, I wish. I wish you could like invest in like micro, micro invest. I'm such a horrible investor. Um, but like I can see it. Like I can see when somebody is just going to take off or like an app is going to take off.
[00:32:18] Kalen: Definitely. You know, like, just like a hundred, just to say, just so you could say you did, you know, like a hundred bucks, like I called it, I called it that that app was going to take off, you know, um,
[00:32:31] David: yeah, that's probably a market for that. I bet you could set that up somewhere on like one of those betting sites.
[00:32:36] Kalen: Dude, that's what we need, man. We need that in the ecosystem, dude. You see a young up and plumber. And you can bet on them.
[00:32:44] David: Yeah. Betting is always helpful for everyone.
[00:32:49] Kalen: That's always a net benefit to society.
[00:32:56] Kalen: Um, nice. Well, okay. So, but wait a second. So then you don't have this problem that, that there's stuff you can't do that Salesforce could do.
[00:33:05] David: Maybe I'm still validating, but yeah, problem, problem, hopefully solved. One of the specific things that, uh, Salesforce had is this concept of price books and a price book can apply to a particular like customer group.
[00:33:24] David: Um, and that allows you to have a full sheet of prices that every product should be for this specific group. Um, so it's not like a pick a collection, apply a certain discount.
[00:33:37] Kalen: You
[00:33:37] David: can just do like, this thing was 89, I want it to be 79. So it doesn't have to be a rate, it's just that this is the price. And Shopify kind of has that with the compare at price, um, but there's shenanigans there.
[00:33:59] David: For example, if you have, uh, if you have. Oh, here's a, here's an interesting problem. We, uh, we have products and variants. Everybody has that. Um, but sometimes we have variants. You're not special, David. Everybody. No, I'm not. Um, but if you like, let's say you have a color that you don't use anymore. Uh, or you like you discontinued an old color.
[00:34:26] David: Right. Um, and that, that variant still lives. On the product, but just that variant is disabled. If you don't also set up the compare at price on that variant to be, uh, to be the new sale price, then instead of getting strikethrough prices on PLPs and stuff, you get a range. And that range has been killing me
[00:34:51] Kalen: for the last couple of years.
[00:34:54] Kalen: But question, when you say, because I ran into this before where I needed to disable a variant because in NetSuite, they can basically do that. They can disable the equivalent of a variant and I looked at it and, and there isn't a way to disable a variant. Like you can delete it or. Yeah, you have to delete it.
[00:35:12] David: Yeah. Which is sad because it's got metafields and stuff all filled out, so if I delete it, then I'm going to have to recreate it at some point.
[00:35:21] Kalen: Those four beautiful metafields, they're just going to get oceaned.
[00:35:25] David: I know.
[00:35:25] Kalen: Yes.
[00:35:29] Kalen: So, yeah. Oh, metafields are so cool. Yeah, that's pretty cool. Um, actually, uh, I'm doing this NetSuite thing, uh, and they have price, like kind of what you're saying, their prices per customer. And they also have, um, per, per customer group. And then on top of that, they also have this markdown or markup. tool where a given user can have a certain number multiplier markup on top of whatever group they're in.
[00:35:57] Kalen: You have some fun stuff there. Yeah, and when we first were specking it out like a few months, like two months ago, I was looking at it and then I was like going, dude, I think these, I think the B2B, um, Price logic is going to be too limiting because like you can do price lists and catalogs, but you can, there's only a very simple markup markdown percentage tool, and if you don't use that, then you have to import individual prices for every product, which gets to be a nightmare for every product and for every customer, um, which gets to be a nightmare.
[00:36:30] Kalen: So I realized we could use metafields and a discount function or a cart transform function, um, To, to, to, to set those prices and then just have a little, the same logic duplicated in the liquid, uh, in the price in the liquid to match up with the function. And, um, and so we scoped it out and then like a month or so later, like the project starts and I was like starting to work on it again and I had forgotten that how we were planning to do it.
[00:37:00] Kalen: And I was freaking out like the other day and I was telling the client like, Oh shoot, like the catalog price isn't going to work for this. And then I was like, Oh yeah, we're going to, you know, do functions and stuff.
[00:37:11] David: But yeah, anytime you have a problem, just remember that metafields exist.
[00:37:16] Kalen: Yeah. Well, but you got to have the functions too, man.
[00:37:18] Kalen: The functions to me are, are, uh, are more, are, I mean, it's not that you have to compare them. It's like, why not have both? But to me, the functions are more, I mean, and the functions rely heavily on metafields. So yeah, the two. The two in unison are a beautiful combination.
[00:37:37] David: I've only done one function and I don't, I feel like there's no apps for these yet.
[00:37:43] David: The, there are, um, fulfillment constraint functions, uh, which have saved my butt. Um, we had a, we had a problem where. Uh, for some reason we were getting, uh, like, let's say someone bought a travel case set and a gift box. Sometimes the travel case set and the gift box would be split, fulfilled between a store and, uh, our warehouse.
[00:38:19] Kalen: And
[00:38:19] David: so I, I made a fulfillment constraint that basically said. If there's a gift box in this, uh, in this order, make sure that everything fulfills together. It sounds super simple, but just getting through understanding how, uh, functions work was kind of interesting.
[00:38:38] Kalen: Yeah.
[00:38:38] David: This app is still in our, this app is still in our store and it's like so simple.
[00:38:43] David: There's one button to either create or delete the function.
[00:38:50] Kalen: Wait, what do you, what do you mean to create, Oh, Oh, the app. Oh, got you to do the graph QL mutation to create the function.
[00:38:58] David: Yeah. That was a bit of a journey figuring that like,
[00:39:02] Kalen: yeah, it's so in order
[00:39:04] David: to write a function, I need to define it. And then I need to like. Create it and then yeah,
[00:39:11] Kalen: yeah, it's, it's, it's always confusing the first couple of times.
[00:39:16] Kalen: Um, dude, that's interesting because I don't even think I realized there was that, that fulfillment constraint deal, because I've looked at a couple of scenarios where somebody is like having some, like what you described, like if an order is stocked in this warehouse and that warehouse, then what happens?
[00:39:36] Kalen: And then there's like the order routing logic. That you can use, but it doesn't, uh, it does some weird things. Like actually somebody had, I think the exact opposite of what you're describing, which is if a, an order had to, okay. It was weird. It was if an order has two items and one of them. Is in one location.
[00:40:02] Kalen: Two line items. One has quantity one, one has quantity two. The first line item is in location A. The second line item has one in location A. And, and then, but, and then it has one in location B. But it'll, the whole order will get fulfilled in location A and it will throw an error that there's not enough inventory to fulfill that second line item with quantity two.
[00:40:30] Kalen: But anyways, I didn't even realize there was a fulfillment constraint function to do that kind of stuff.
[00:40:36] David: Oh yeah, like I feel like this is um, when I started writing this fulfillment constraint thing I couldn't find any apps for it and I was like okay this is going to be the app that I make. And I was dead set on like making an app and then I started to think about what does it mean to have an app in Shopify?
[00:40:58] David: Well, I'm going to have to support it. And after that I was like, okay, maybe I won't make a Shopify app. Yeah. I
[00:41:11] David: feel like that's another thing for apps that is, uh, like a very easy indicator is if they've got live chat and you can talk to someone about something and they're helpful.
[00:41:24] Kalen: Yeah. Boom.
[00:41:27] David: I need you. Yeah. Yeah.
[00:41:28] Kalen: Yeah, it's funny because I was looking at an app called a checkout links. I was doing some work with them and, uh, some flows with, uh, Dennis, the founder.
[00:41:37] Kalen: And, um, I, so I installed his app and it had a nice checklist onboarding flow with the steps you needed to do. And then I go, I was like, I was like, this is the perfect onboarding flow. And, um, I was gonna, um, um, Tell him that. And then in that moment, his live chat thing. Did one of those auto pop ups, uh, where it says, Hey, let me know if I can help, you know, the intercom chat bubble.
[00:42:07] Kalen: And then I was like, dude, I hate those so much. I was like, I told her, I was like, I was going to say that your onboarding was perfect until I saw that. But, but he, but he, but he said that, but I was like, I, but I was like, I know I'm more of a minimalist and I'm sure there's a lot of people that that's helpful to get that auto pop.
[00:42:26] Kalen: Deal, but, um, but, and he said, yeah, like regular customers, like love that stuff. Um, you know, like normies, like you're like, you're obviously a total, total, total normie. Um,
[00:42:38] that's another one of those like secret ways to talk shop with someone is just like jumping in one of those chats and being like, Hey, Hey, what's up?
[00:42:46] I don't really have any requests. I just want to see how's it going. Right, right, right. How about that e commerce?
[00:42:54] Kalen: When you're feeling lonely, just bop into an app. Chat with Gil on checkout blocks. That's right. What's going on, man? Not anymore. Yeah, not anymore, dude. He's fully corporate now, man. Oh, man, he did it.
[00:43:08] Kalen: Yeah, he did it, man. He pulled it off. It's pretty, pretty nuts, dude. Um, yeah, dude, it's crazy, man. I feel like his tone is different now. I don't know if I'm just imagining it, but he just, he seems more pot, like, like a little bit, like just a little, like not as raw, I guess. I don't know. Maybe I just haven't been seeing enough of his.
[00:43:32] Kalen: No, maybe. I'm sure he's a bit
[00:43:34] David: relieved. Yeah.
[00:43:36] Kalen: Yeah. I
[00:43:38] David: don't know. Never, never built and sold an app.
[00:43:41] Kalen: Yeah. Yeah. Yeah. It's a, that was a huge acquisition. I mean, that was super impressive and it's great. It's really cool how they just rolled it in and, um, and then, um, uh, you know, made it basically all free. Like I think most of it is all free.
[00:44:01] David: Step four upsells, which I, I was curious about and I asked about it and hopefully I'm not the reason they removed those. I'm sure they had a lot of questions about it, but I was like, Oh, check out blocks is free now. I get to do Upsells in the cart. Nope,
[00:44:20] Kalen: but how appropriate for the upsell feature to be the upsell.
[00:44:24] Kalen: That's awesome That's perfect,
[00:44:29] David: yeah, I'm sure there was something about like Upsell apps that weren't owned by Shopify were sad about competing. I don't know. Right. They probably have to think about, like, I'm sure they think about this stuff all the time, making sure they don't, uh, compete with app devs.
[00:44:45] David: But at the same time, you also see them like making apps sometimes that destroy certain segments. So I don't know how that works.
[00:44:53] Kalen: Yeah, I'd imagine they're kind of aware of it and like they're not gonna create an app unless there's probably like a lot of reasons to do it and it like, I'd imagine it's probably pretty, it's probably got to be like pretty obvious for them.
[00:45:11] Kalen: That an app is needed by the time they create one, you know, because they probably hearing so much from so many different people across so many different teams, like subscriptions, like we need subscriptions, like, you know, by the time they actually think
[00:45:26] David: about it, like a lot of the apps that Shopify has on the app store have really bad ratings.
[00:45:34] David: And I think it's because they're, they're just making a proof of concept to like, get the, get the ball rolling for someone to beat them.
[00:45:44] Kalen: Yeah. Yeah. I think the way Toby says it is to raise the floor for, for the space, which is always what I.
[00:45:53] David: I think of it. Um, yeah, it seems like it's working there. There is like, while there is a bit of a, um, gap, uh, of quality, it does feel like overall it's, it's continuing to increase,
[00:46:10] Kalen: I think so dude.
[00:46:11] Kalen: Totally. Like, like there weren't any subscription apps that were killed in the making of that, you know, like they're all still here, you know, like, um, so I don't think it's. I don't think it's too much. Same with bundles. Like, I don't think it's too much of an issue. Yeah. Dang, I had something that came to mind and then I totally forgot.
[00:46:32] David: I need to make it out to one of those. Things have to try and do it next year.
[00:46:36] Kalen: Oh yeah. One of the events.
[00:46:38] David: Yeah. Yeah. I got super busy this summer because, uh, multiple reasons, but one of them is my, my wishlist app got shut down, so I had to get a new one running. And then, um, I decided to switch reviews.
[00:46:57] Kalen: Your reason for not going to the event is because of your wishlist app. So that's like, maybe
[00:47:05] David: I shouldn't
[00:47:05] Kalen: have
[00:47:05] David: started with that one,
[00:47:06] Kalen: but you're like, because, uh, multiple reasons and
[00:47:12] David: starting with the, the one that's not. Oh, I also went to a Disney world this year. That was another reason.
[00:47:21] Kalen: Oh, so that's a
[00:47:22] David: good reason.
[00:47:23] David: Um, Should've started with that one.
[00:47:24] Kalen: Yeah, you should've started with that, dude. Um, that's cool, man. Did
[00:47:32] David: you, did you like it? Yeah, it was great. We, we went to a couple different hotels to check it out. We know someone who works there, so saved a little bit of money, but it is not cheap to just like be there.
[00:47:49] David: Oh dude, it's crazy.
[00:47:52] Kalen: Dude, it's a whole, it's a whole industry. Like when I found out that people sell planning eBooks for Disney world trips, 10 planning, I about lost my mind, dude. I was like, That's immediately where my mind went. How could I get in on this action?
[00:48:21] Kalen: That's crazy though, dude. That's so crazy. I wish I was, I wish I was more able to enjoy the Disney World thing. I kind of just, the last time we went, I kind of just powered through.
[00:48:31] Kalen: I finally remembered the thing I was about to say earlier, which was that. It's funny with apps because when, like when somebody, like when some, somebody is pitching you on something or even if I'm asked, even if I ask a question about a problem I'm trying to solve, like, how do I do this, uh, I don't know, whatever.
[00:48:51] Kalen: And if an app. Person mentions an app, like by default, I'm just like, not interested. And maybe if it does exactly what I'm looking for, and it's like built for Shopify and you know, the person, then you're like, cool. Um, but on the flip side, when, when you stumble across an app that does exactly what you need, there's nothing better, you know, and, or like when you tell, tell me about an app that solves a certain thing, like perfectly, it's like.
[00:49:25] Kalen: That's awesome. You know, I guess I'm trying to say there's this like huge dichotomy in when somebody's pushing an app on me versus if I come across an app myself or through somebody recommending it. You know what I mean?
[00:49:39] David: Yeah. There's someone like, right. So if someone is selling me something, I'm turned off.
[00:49:45] David: Yeah. Um, yeah, that is a weird feel. And I have the exact same thing.
[00:49:54] Kalen: Like there's times when I feel like I hate apps, like I would just say I hate apps because I'm sick of hearing about them. I like the less apps my client has, the better. I don't want, you know what I mean? And then, but then when you find a cool app, You're like, I love apps.
[00:50:10] Kalen: Like this app is great. Like when you said Salesforce had discount stuff, the Shopify doesn't have, I was like upset. I was bothered about it. I was like, let's get this fixed. And then when you mentioned the Regio one, I was like, We got this dude, problem solved. Save the day. What's your problem
[00:50:29] David: though? Why would you even say that?
[00:50:31] Kalen: We're good to go, you know?
[00:50:36] David: No, I agree. And that's probably like, again, the, the quality gap thing.
[00:50:41] Kalen: A
[00:50:43] David: lot of what I try and do with our store is stay as native as possible. And like only, only add when we absolutely need to, because I know Shopify is working on lots of cool stuff. And as soon as I am beholden to an app to do whatever, and then Shopify comes out with some solution that maybe, maybe solves a different problem, but still could be used in this case.
[00:51:14] David: It's like, okay, well, maybe it doesn't make sense to use that from Shopify. Bye. Because we're already in this other place and it's going to take me like two weeks to get out of it or more. Um, so that's, that's, uh, one of the anxieties that drives my decisions on our stores, like, uh, how to make things, uh, least complex as possible.
[00:51:38] David: And most of the time that's by just sticking with what Shopify has.
[00:51:41] Kalen: Yeah. Yeah. Because it's like the problem might be solved in a different way, sort of a different underlying model. Or like the other thing too is that like apps are like, there's so much overlap between apps, um, solving multiple problems, solving the same problem are there any problems that you're currently trying to figure out how to solve that you're not sure how to solve? And also, which email address would be best for the Sass, uh, guys to pitch you, to pitch you at?
[00:52:17] David: Problems. I'm trying, I, whenever I think about stuff like this, it's never. Um, like technical e commerce problems, it's more like,
[00:52:29] Kalen: um, problems and management.
[00:52:33] David: Yeah. I have people, but like we, our creative team is awesome and they go out on location and shoot the most beautiful photography and, um, they work really hard on designs and, and like coming up with a concept.
[00:52:50] David: Uh, for the site, and it's always a bit tough to stay like to, to keep up with, um, slight changes that they want to make to certain layouts. And, um, so we spend a lot of time trying to figure out the best, uh, setup for components in the theme editor. I shouldn't call them components like sections and, um, what setting should we have in the section so that the team can easily make things so, um, and that's really hard.
[00:53:33] David: Like we, one of the things I've talked to you about before is, uh, we use meta objects to populate content on our collection pages.
[00:53:41] Kalen: Um,
[00:53:43] David: and, uh, collection collections and Shopify are just lists of products. Uh, you can't pick variants. So we have like a way to pick variants. Um, and then the way that we solved injecting content is, um, uh, I feel bad for admitting this, but it kind of sucks.
[00:54:07] David: Um, every time you output, uh, so when you're rendering a collection, maybe this is going a completely different direction from what you were looking for with this question, but, um, uh, so you're outputting products one at a time. And the way that we decide where content should go is based on a product reference on a meta object entry.
[00:54:36] David: So every time you output a product, you have to run through all of the meta object content. And see if any one of them should be inserted before or after this one and then output it, which worked great to start. But now, like, we were working with the creative team. I'm like, what would it look like if we had, uh, content injected that took up 2 rows?
[00:55:01] David: And that just changes, like, all the stuff. So, okay, now we need to flow the product tiles in around that thing. How should that, like, how do we make sure that the bottom of that content matches up exactly with the bottom of the image from the product tile next to it? And that, that's the kind of stuff that I, that we spend a lot of time on, trying to make sure is right.
[00:55:20] David: Um, and then, like, before it even gets to the technical, like, get an output onto the site, the, like, the project management of, uh, meeting with the creative team, talking about what, what kind of things are scary or, or not too scared about, um, especially with it, like, being fuzzy all the way up until, um, like, the days or week before, um, that's one of my, probably one of my bigger challenges.
[00:55:49] David: Gotcha.
[00:55:50] Kalen: Yeah, I got nothing for you. It sounds complicated, but we'll have the sass guys. We'll have the sass guys. Oh yeah, reach out. Um, you know, uh, um, shoot, I was about to say something and then I, and then I forgot again. Um, yeah, I think that, well, one thing I was gonna say was, it's like, It seems like you, like every time you talk about your job, it just seems like you really love it, which is, um, which is cool.
[00:56:25] Kalen: Like, I'm kind of, I'm jealous of that. Like, even, even, even when things are going okay for me with, like, being self employed, like, it's always a little chaotic and I kind of, I love the idea of just being in a place that you just, like, love it there, like, love the people there, get to do cool work and stuff like that.
[00:56:48] David: Yeah, it is great working with, with good people. I, I probably, uh, don't present the amount of stress that I actually feel well. So maybe, maybe that's part of it. Um, but yeah, it is fun. Like
[00:57:07] Kalen: I'm not happy at all. I'm
[00:57:14] David: tired of this grandpa.
[00:57:18] Kalen: But yeah, no, like that, I think that happens all the time where you, you go with a solution and it, it works.
[00:57:24] Kalen: And then later on. Like, you run into something else and you're like, Oh God, we should have done this differently, or I'm running into that myself with
[00:57:38] David: Especially if you start to get crazy, like, I don't know how your NetSuite integrations work, but a lot of ours are based on safe searches. And then you just get like, you just get to see what's in the safe search and then do stuff based on that.
[00:57:54] David: And that ends up with a lot of overwiring where it's like, something didn't work. Well, we've got a big launch today. Where's the inventory? Which switch was it that we missed? Um, always fun.
[00:58:11] Kalen: Dude, Netsmith is so slow. It's so slow. I was using this ERP called acumatica recently, which I think is, is even older and clunkier, but it was fast, dude.
[00:58:28] Kalen: I mean, it was a little silly looking the interface, but it was just like snappy, man. It's like quick and I was like, I have
[00:58:36] David: like. That's what it's got to be running on like some old cable boxes or something.
[00:58:41] Kalen: I have a query that runs nightly that takes an hour or a minute and a half to run one query, but it's, it's grabbing a lot of data.
[00:58:51] Kalen: But
[00:58:53] David: yeah, that is one of the things that everyone's been super happy with on Shopify is just that like you can log in and click something and something happens instantly.
[00:59:02] Kalen: Yeah, and I mean even even Shopify like when I first started using Shopify I thought it was a little bit slower than what I somehow expected that it would just be like this lightning fast You know like almost like Gmail type speed.
[00:59:18] Kalen: Yeah But yeah, I mean compared to Any any any other like ecommerce software? It's like amazing Um, and it does go down, I mean, you know, it goes down like, it's funny because it sort of goes down relatively frequently, but I think, and people will always say something on Slack when it goes down, but I think it's probably sort of isolated what, what's going down, like, what's not, yeah, a lot of the time
[00:59:48] David: it's the admin, right, right, right.
[00:59:52] David: But every time that happens, I am like, okay, now I got to go to the front end and until it loads, I'm very nervous. Yeah.
[01:00:02] Kalen: Does the front end ever go down? Like in those scenarios? It has
[01:00:05] David: before. Yeah. But, um, maybe only like once since we've been on it for a short period of time.
[01:00:15] David: . Good times.
EP 1: The Upsell is the Upsell

© 2025 All Rights Reserved SCORE: 0

Kalen
Punch Kalen - @kalenjordan
David
Punch David - @d_rbn