Elvenda April Update

tl;dr: We onboarded some stores, some things were broken.

Quick April update. Live suppliers: 3 Live dropshippers: 0 Revenue: $0

What went wrong last month?

Issues with real users in production were both exciting and demoralising. A user goes down the wrong path and causes a condition without an error handler, and that’s it – they’ll never be back.

It’s a 10 minute fix of course, but that guy won’t be back for a year. We had 4 or 5 of these critical errors in real paths users take.

Every issue I’ve fixed this month now has a unit test attached to it. This means the code didn’t have coverage in the first place. I’m standing by that.. I don’t think it’s right to spend precious hours (on a time and motivation constrained project) testing shit that probably isn’t broken.

Of course, we’ve paid the price for this. It sucks so much seeing that a user won’t be back because of code you wrote (or, didn’t.. As the case may be)

Content/Marketing?

Our content marketing is going OK. Each week we get more impressions than the last. Google search console is showing key terms that are important to us.

We’re slowly learning to output better and longer content. But most importantly, we’re putting out a lot. It’s easy to get side tracked from that. I like to think an hour spent on a well targeted, well researched article that can help our users will pay itself off many times over the expected lifespan (this is a post in itself – unless we end up in legal trouble or something, this tool is sticking around).

I wrote an article I’m pretty proud of, about setting up dropshipping with WooCommerce.

Technical next steps

I’m not sure much needs to be done on the technical side until we have some real users. We need to double down on reaching out to people.

A clear issue came up last month that we need to uncomplicate. To properly set stock counts, list prices, minimum sale prices, a user needs to export, edit, and then re-import a CSV. They all got stuck on it, in creative and different ways. So we’ll be working on a grid style editor for that, that at least cuts out the export and import steps.

We keep live smoke testing the order path and everything is working. But, everytime we onboard someone new, they find some new things. I guess it’s the nature of third party integrations with people at the low end of the budget spectrum – there’s going to keep being capacity and security constraints.

People with proper budgets aren’t going to give a shit about us for a year or two, so this is the crowd we need to make happy first.

I think the technical next steps at this stage need to be defined by the issues that the next batch (“Batch” is loosely defined, since it’ll probably be like 3 stores) find. So we need to find that next batch.

Summary

We’re still marching to dollar number 1. It’s hard to tell how far away that is at this stage, but its a hell of a lot closer than it was 4 weeks ago.


Software engineering in the future

Just a short article. I’m interested in how software engineering is converging into niches. It’s interesting to think about where to position oneself.

Just as everyone “learns to code”, as is touted so often, are we going to have an order of magnitude less coding that needs to be done?

Big Co’s: AWS. DevOps. API as a Service. Nothing on-prem. Not a lot of software dev occurs. Outsourced dev to people factories when necessary. Most everything they need exists as an ‘enterprise’ plan of some SaaS, or can be clicked together with AWS. Everything has an API, and everything is connectable with stickytape and API proxies.

Medium Co’s: SaaS where practical. A few in-house developers – no budget or means to find people factories. They’re a little big for SaaS for everything, or a little bit niche and the product doesn’t exist yet. The in-house devs firefight this custom made stuff.

Maybe still use on-prem mostly, with a sprinkling of AWS.

Small Co’s: SaaS for everything. Google Docs, Xero, IFTTT. Nothing on-prem. If it doesn’t exist as SaaS, they don’t do it (or write it themselves, to their peril). They don’t use AWS at all as a first class customer.. But probably all of their services do.

I wonder what the equivalent of a plumber is for software developers (you always need someone to unclog your toilet).

Fix CORS errors on local node server

When hacking together a quick throwaway node server, it’s easy to get caught going around in circles with Cross Origin Resource Sharing and Access Control Allow Origin.

Here’s a quick and easy way to disable this so you can keep moving.

I’m using node’s http package via http.createServer.

const http = require('http');

const requestHandler = (request, response) => {
    let chunks = [];

      const headers = {
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
          'Access-Control-Max-Age': 2592000, // 30 days
          "content-Type": "application/json"
          /** add other headers as per requirement */
      };
      response.writeHead(200, headers);
// do other stuff, output JSON.
response.end(JSON.stringify(obj));

function startServer() {
    let server;

    server = http.createServer(requestHandler);
    let port = 3000;
    server.listen(port, (err) => {
        if(err){
        console.log(err);

        }
          console.log(`server is listening.`);
    })
}

startServer();

Build a reverse image proxy in 10 lines of PHP/Laravel

First up, there’s better ways to do this. Maybe you should use nginx, and keep this out of PHP altogether. Maybe you should pull down people’s images, host them locally, and then serve them up yourself.

This isn’t about the best way. For me, tonight, this 10 liner that doesn’t mess with my nginx config is the best way.

Why build a reverse image proxy in PHP/Laravel?

We want to use image data from connected stores’ websites. We want the images to be fairly current. We want them to load super fast. And we want to load a lot of them at a time.

Connected stores are WooCommerce, Shopify or Magento. WooCommerce is known for being hosted on shitty $9/mo VPS plans, and they’re easy to kill with 50 fast requests for full sized images.

We use CloudFlare to cache assets aggressively, and it’s a total no-brainer. Can you convince your freemium customer to do that, who doesn’t even know where their DNS records are hosted? No.

So, instead of requesting images from the connected store site directly, we’re proxying them through our server. The server goes off and loads the image, and returns it to the app. Cloudflare captures the response and caches it for next time, so we only serve it once.

The code


Route::get('/external_resource', function(\Illuminate\Http\Request $request){
$resource = $request->get("resource");

$options = array('http' => array('user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'));
$context = stream_context_create($options);
$f = file_get_contents($resource, false, $context);

$finfo = new finfo(FILEINFO_MIME);

$contenttype = $finfo->buffer($f);
header("Content-Type: " . $contenttype); //HTTP 1.1

echo $f;
});

What’s it do, in detail?

Pull a URL out of the ‘resource’ get param, e.g. https://app.elvenda.com/external_resource?resource=https%3A%2F%2Fpioneergear.com.au%2Fwp-content%2Fuploads%2F2017%2F05%2Fhat1.jpg

Fetch the underlying image, with a chrome user agent (Shopify was 403’ing the requests).

Setting the content type to the content type of the image

Returning the image to Cloudflare, who return the image to the browser.

Articles I need to write

This post isn’t for you, it’s for me.

How To: Setting up a gitlab CI pipeline for React Native

How To: Setting up a gitlab CI pipeline for Laravel

How To: Screenshot testing in React Native

I built (and sold) a payment gateway

Side Project Progress

First Store.. 1 day away?

Our side project, Elvenda, is a B2B dropshipping platform. You sign up as a supplier and receive orders, or sign up as a dropshipper and get a ton of new products.

It’s pretty cool. It’s a totally different take on a model that’s been done before, so we’re interested to see how it goes once we land a few stores.

We’re laying the tracks as the train is coming along behind us, which is a fun kind of stressful. I’m still coding up critical parts of the app – you couldn’t filter products until yesterday. But of course, the clock is ticking and we need to validate this idea, so we can double down or get on with our lives.

Tom, the other half of the project, is emailing customers like crazy trying to get them to try out the platform. We’re not just building this thing in the dark, we’re talking to people who are excited and who want to use the project. Without looking at the numbers, it feels like 10 emails leads to 2 ongoing conversations leads to 1 person who creates an account.

We’re super happy with that – we’ve got no social media presence, no google search presence, not much content, and the app is pretty barebones. Hopefully that metric just gets better over time, and hopefully we start ranking for some organic long tail terms over time too.

Tomorrow is the day that we’re going literally knocking on doors. Tom and I both used to work for an ecommerce store, and we’re going in together for a chat and hopefully walking out with our first connected store (who also has thousands of SKUs, so it’s a heavy hitter). Then out for a burger to commemorate our first store.

Tech that lasts 40 years

I watched some Microconf videos last night on https://microconf.gen.co/. I’m not sure if it’s strictly ‘legit’ or if this guy is just putting a camcorder on the seat and videoing Microconf.

I’d badly like to go one year, and it’s always been something I want to reward myself with when I get a SaaS to the stage where I can justify the lessons. Most projects I work on don’t live that long or progress that far. I like to think the Microconf organisers will get my money one year. The dodgy camcorder on the seat is probably drawing me in more. I get to hear the talk and get a feel for what’s going on, but the experience is still dodgy. Who knows what’s on the slides.

I like to distill these videos down to nuggets of gold, and hopefully I’ll remember them later.

Patio11/Patrick McKenzie has friend catchers. In real life, this is leaning yourself in to activities that can attract friends. His example is learning to cook – learn to cook, and any time you can invite some friends over for a meal. You can have friends any time.

The tech equivalent is solving people’s problems. Become a ‘people with problems’ catcher (that, you know, they’ll pay for). Where can we find people with problems? How can we help them solve them? Will these turn into ideas, or side projects? Or even just client projects.

Another thing he kept drawing back to was creating things that will last 40 years. We’ve got 40 years of blog posting, open source projects, podcasts and youtube videos to create.

When I’m working on something, very rarely can I honestly say I’ve cared if it could last 40 years. What might I do differently? He publishes his email address and says ‘this is my email address for the next 40 years’. I think the 40 years thing is going to stay with me.

I’m trying to think what’s still going to be around in 40 years. It’s difficult.

– gmail, yes. I would’ve said this about AOL though.

– AWS, Azure, yes. I would’ve said this about Geocities.

– iPhones. Surely not..?

– Wikipedia?

– Basecamp? These guys say Basecamp will be around until the end of the internet. If there’s some way to serve Basecamp to you, they’re going to work it out.

I want to make something that people in 40 years could use. It doesn’t have to be ubiquitous, in every household or any shit like that. Just that they *could* use. My grandkids can clone it from github (Remember when you used to install everything from sourceforge?), install node, and spin up a server of something I did.

It’s a humbling idea. I’m not sure if I’ve worked on something yet that has a half life of >5 years. I’m not really ok with that.

ag: Fast searching source code

From the “I’m shit at command line” category

  1. brew install ag
  2. Ignore files that are autogenerated. Also honours .gitignore! cat 'android.bundle.js' > .ignore
  3. ag MY_SEARCH_TERM
  4. Profit!
some-app/some-node-file.js
5:    username: 'MY_SEARCH_TERM',

Nice, fast, clickable results in vscode.

add zipalign to path on OSX

First, find zipalign.

find ~/Library/Android/sdk/build-tools -name “zipalign”

Copy the most recent build tools version, e.g.

/Users/me/Library/Android/sdk/build-tools/28.0.2/zipalign

Add it to /etc/paths.

nano /etc/paths

(Paste the zipalign path)

Save and exit ctrl+o, ctrl+x

Close the command window.

Talking to customers / cheapening the brand

I’m working on a side project with a friend (/my brother in law) that connects suppliers and brands to dropshippers. It’s a business model that’s been done before – we’re just taking an existing model and fine tuning it, maybe making it more Australian. It’s called Elvenda.

We’ve got a functioning beta at https://www.elvenda.com. I’m still working on developing the back-end for a few hours a week here and there. My brother in law is spending an hour or two a day reaching out to potential customers. We’ll criss-cross on all that over time, we’re both developers and both wear a lot of hats.

It’s a slow burn. We know there’s a market here, we’re not 100% sure how to reach it yet, and we know we need to slowly stack bricks on it for a few years.

I’m writing about the pain points that customers have raised so far, and the issues with the model we’ve chosen and dropshipping in general. We both run or have run e-commerce stores currently or in the past, so we’re aware of the general problem domain.

Issue 1: Cheapening the brand

Here in Australia, Amazon hasn’t decimated online retail. We’ve got strong brands, and it’s not uncommon to make a reasonably high value purchase from a store you haven’t heard of before. We’ve got strong consumer laws and clear paths to resolution if there’s an issue. Not least of which is PayPals buyer skewed policy.

Not surprisingly, online stores in Australia are terrified that sometime soon, Amazon will wipe out our online retail margins. So brand owners are terrified that we/Elvenda will help contribute by making dropshipping fairly easy, and making it easy for dropshippers to knock the margin out of products. 

Scenario 1: Supplier makes product with RRP of $100 available for $60, dropshipper sells for $62, now we’re all fucked.

Scenario 2: Supplier makes product with RRP of $100 available for $60. Market sees that somewhere in the supply chain it’s available for $60, market demands the product for $62, we’re all fucked.

These are slightly different – scenario 1 is about the availability of the product at a price, and scenario 2 is the market knowing about it.

When potential customers of Elvenda started saying to us that this service was going to cheapen their brand by blowing away margins, we weren’t really sure how to fix it. They’re right – it’s a certainty.

The other issue we’re lumping under ‘cheapening the brand’ is availability of products. Some products have a scarcity about them – they are only available at niche stores in Berry or at a one of a kind store in Sydney. If the products are appearing on eBay now, the magic of the brand is dead.

How we’ll make sure we don’t cheapen the brand

To summarise, here’s the issues. Over-availability of a brand’s products. Availability of brand products significantly below RRP (enough to damage). Market awareness of margin in brand products.

Here’s how we’re going to fix it. 

Brand product availability

A supplier or brand owner who lists their products for sale on Elvenda has total control of who will be able to dropship their products. A dropshipper needs to apply to a supplier, and the supplier can vet the store to make sure it represents their brand values and manage their own product scarcity with this process. Only want to be sold in high-end stores? Fine, only approve high end stores.

Protecting supplier and dropshipper margins

A good supplier on Elvenda can offer their products at a list price where the supplier can make a healthy margin and so can the dropshipper. We don’t want to punish the supplier by setting up our platform for dropshippers to screw their margins away (by selling the previously mentioned $100 RRP product for $50).

Since both the supplier and dropshipper are connected by our platform, the solution to this is simple. We won’t accept an order from a dropshipper who has sold the product below the agreed minimum retail price. There’s no circumstance where a dropshipper can sell below the minimum that a supplier has specified. Fixed!

Protecting availability of trade/list pricing

This is a less important issue and a harder issue to fix. A reasonably awake consumer knows that every stage of the supply chain takes a cut, and a $100 product started life as a few $1 components.

We certainly don’t want to be the ones leaking this information to consumers however.

Brands and suppliers listing their products on Elvenda will have their trade/list pricing hidden from potential sellers/potential dropshippers if they require approval. Only once the supplier has approved the dropshipper will trade/list pricing become available.

We can’t protect the information after that of course, but we’re doing our part to make sure that we aren’t leaking this information to dropshippers with prying eyes 🙂

Cheapening the brand ended up being a long article in it’s own right, there’ll definitely be more as we keep getting to know potential users. The app is at https://www.elvenda.com, and it’s for connecting suppliers to dropshippers in the easiest (read – most automated) way we know how.