1 bit short of a byteMy corner of the internet.2020-12-29T16:14:16+00:00https://evan.verworn.ca/Evan Verwornevan@verworn.caGoogle, fill the niche.2019-11-04T00:00:00+00:00https://evan.verworn.ca/posts/fitbit-acquisition/<aside>
<p>Google has announced they have purchased Fitbit, the defacto brand of activity
tracker on your wrist, for a cool 2 billion.</p>
</aside>
<p>Hi Google,<br>
How are you doing?</p>
<p>I've noticed that with this and previous acquisitions you've bought two
(partially three) watch companies. Fitbit, Pebble and Fossil.</p>
<p>Now there are a few people out there that <a href="https://www.androidpolice.com/2019/11/02/pixel-watch-or-not-fitbit-cant-save-googles-failing-wear-os/">don't believe you'll do anything
meaningful with these companies</a>, and to be fair they make good
arguments. But what they don't mention what all three of these companies have in
common.</p>
<p>They all became famous, for their <strong>low powered, long lasting</strong> devices.</p>
<p>Fossil, with their <a href="https://www.fossil.com/us/en/wearable-technology/smartwatches/hybrid-smartwatches.html">hybrid watches</a> with batteries that last <em>6
months</em>. Fitbit, with their one week (originally display-less) <a href="https://www.fitbit.com/en-ca/flex2">Flex</a> devices<abbr style="font-size: 70%; color: var(--accent, blue);" title="It seems all of their devices now last a week?">[1]</abbr>.
And lastly <a href="https://en.wikipedia.org/wiki/Pebble_(watch)">Pebble</a>, the famous e-paper watch with a battery life of 10 days.</p>
<p>Compare those numbers with the Apple Watch's <a href="https://support.apple.com/kb/SP778?locale=en_US">advertised battery
life</a> measured in <em>hours</em>. I
concede that the Apple Watch does more than the previously listed devices, and
Google you're allowed to make a luxury device that directly competes but may I just conject...</p>
<p>What made all of these aforementioned devices <em>great</em> wasn't the screen. It
wasn't the pixel density, it wasn't the refresh rate, it wasn't the colour
gamut. It was what these devices enabled -- in spite of -- their screen. I'm
going to go out on a limb and say "Most people don't need to watch YouTube on
their watch."<abbr style="font-size: 70%; color: var(--accent, blue);" title="And even more "shouldn't"">[2]</abbr></p>
<p>What made the Casio great wasn't the look. No, it definitely wasn't the look. It
was what it allowed you to do, despite the look.</p>
<p>So just to make sure you include everything you need I'll make you a quick and
easy checklist of features, <em>ordered by importance to me</em></p>
<ul>
<li><label><input type="checkbox"> Minimum 2½ day battery life</label>
I should be able to go for a camping trip weekend, don't tell me it can't be
done, I just listed a bunch of devices that do. At least provide a "low-power
mode".</li>
<li><label><input type="checkbox"> Water proof to 3 meters.</label>
I can't believe I have to even mention this.</li>
<li><label><input type="checkbox"> Heart rate sensor.</label>
Super useful for fitness training, and health reasons in a world with people
with heart conditions.</li>
<li><label><input type="checkbox"> Tells the time</label>
Somehow.</li>
<li><label><input type="checkbox"> Wirelessly charges from your phone</label>
Don't give us <a href="https://i5.walmartimages.com/asr/4c1de1de-47d9-4259-a90b-b7494940048c_1.f5cc0b195cb71a11808ac2a4c4bab5de.jpeg">this nonsense</a>,
give us <a href="https://www.samsung.com/us/support/answer/ANS00082564/">wireless charging and device charge sharing</a>. I should be able to place
my watch <strong>on my phone</strong> to have it charge.</li>
<li><label><input type="checkbox"> Bluetooth music storage</label>
We're getting to the things that are just "nice to have", but being able to
just run without bringing the phone along would be huge.</li>
<li><label><input type="checkbox"> GPS</label>
Both for time synchronizing, time zones and fitness tracking. Plus remember
above? We don't want to bring the phone everywhere. We don't need turn-by-turn
directions, but a <a href="https://i.pinimg.com/originals/f7/1a/81/f71a8149094f69dcaad692b6035d127f.gif">"Jack's Compass"</a>
that always points home? That's useful.</li>
<li><label><input type="checkbox"> Notifications</label>
Let us know when <abbr title="A reminder to you reader, you should call your mom">mom's calling.</abbr>
You can do a lot, with just an LED and/or vibrations.</li>
</ul>
<style>
ul {
list-style-type: none;
font-size: 80%;
line-height: 1.1;
}
label {
display: block;
font-size: 20px;
margin-bottom: 0.2em;
}
</style>
<p>You'll notice that I didn't mention a display in that list. It's because I don't
think it's necessary. And the companies you (Google/Alphabet) acquired don't
think so either. They found other alternatives like e-paper, physical time piece
hands or just omitting them altogether.</p>
<p>You are now in a unique position with all of your money, software developers and
these newly acquired patents.</p>
<p>You want more companies to adopt your WearOS? Make it run on devices that don't
look like cropped phones strapped to your wrist. Make a device that solves our
social problems by getting us to leave our phone at home and participate in
social situations, not one that just <a href="https://xkcd.com/2223/">increases screen time</a>.</p>
<aside>
<p>Also the size of that legalese at the bottom of <a href="https://www.blog.google/products/hardware/agreement-with-fitbit">your optimistic post</a>
is hilarious.</p>
</aside>
Feed Stabilized2019-07-26T00:00:00+00:00https://evan.verworn.ca/posts/feed-stablized/<p>For the few people who may have been using my feed. I promise it's been
stabilized now. I won't touch the <code>entry.id</code>s anymore.</p>
The Family Network2019-07-18T00:00:00+00:00https://evan.verworn.ca/posts/the-family-network/<p>So I have this backup problem. I have a wonderful RAIDed NAS with more than
enough storage and it's all sitting in my home. If I were to have a fire, or a
theft no amount of RAID will save that data. My parents, cousins, aunts and
uncles (for the most part) also have this problem. Most have a single large
spinning hard drive that they call their "backup drive" and they move their
photos to that backup drive to "back them up". Then promptly delete the original
off of their computer to save space... The goal is to help everyone here,
everyone gets offsite backup, everyone gets a real tested backup procedure.</p>
<p>There are some odd features that I want though</p>
<ol>
<li>Accessible without port forwarding or modifying their network.</li>
<li>Can be setup without installing software on the client machines.</li>
</ol>
<p>The first point is there because I don't know what each of my families use for
their router, and while I'm sure all of them have <em>port forwarding</em>, I don't
really want to be the one managing that. And additionally, I wanted this to
work on phones, which have very complicated firewalling when on cellular data.
Also I just don't want to be responsible for their computers directly
accessible via the internet. Call me paranoid.</p>
<p>There is a lot of things your computer can do already. It has a browser, most
likely a comprehensive router and firewall and a VPN client that works 90% of
the time. Speaking of...</p>
<h3>The Plan</h3>
<p>Setup a VPN server and create a separate subnet where everyone on it can see
each other, without routing <em>all</em> internet traffic. I'm not trying to anonimize
your online browsing. I just want you to be able to type</p>
<pre><code>\\evan.famjam.net
</code></pre>
<p>and see my shared folders. <strong>Without</strong> exposing my SMB ports out to the entire
world.</p>
<h3>Why Should I Join?</h3>
<p>As a family member why should you join my little network? What does it enable
you to do? Everything you could do on a LAN, which means</p>
<ul>
<li>Your Windows/Mac file or screen shares will be viewable, <em>anywhere you are</em>.</li>
<li>Private services, hosted by other families in the network.
(Plex, Sonarr, Ombi, etc).</li>
<li>Dead simple off-site backup. You can setup your TimeMachine (or whatever
backup service you use) to be sent straight to another household. Because
everyone is directly connected together, like a LAN. All without anyone
having to expose their ports to the internet.</li>
</ul>
<h3>But.. Privacy</h3>
<p>So let's talk about the elephant in the room.</p>
<blockquote>
<p>But if I can remote into my machine from anywhere, doesn't that mean <em>you</em>
can remote into my machine from anywhere?</p>
</blockquote>
<p>No, because you have a password on your computer. You <em>do</em> have a password on
your computer, right?</p>
<p>In all seriousness, Windows for the most part actually has a very robust
firewall (remote desktop and file shares are only available to your local
subnet, not the VPN subnet by default). Only services you purposefully expose
will be accessible. And the modern defaults that other operating systems set
means that nothing unexpected should be available out of the box to your other
<em>family members</em>. Because that's the other thing, this is your family. These
aren't rando strangers on the net, or big faceless corporations. This is Aunt
Sally from 5 streets down, or Cousin Vinny the movie buff living 30 minutes
out. If someone does something you don't like, call them.</p>
<p>This also doesn't mean that by connecting your computer I get access to
everything on your network either. Only devices that directly join the VPN are
visible, which means I can't cast to your Roku stick from my house.</p>
<hr>
<p>But I really do think this will enable a better closer knit community that
doesn't need to rely on 3rd party solutions and can self host shared resources
for everyone in their "family".</p>
The IndieWeb is Cool2019-06-12T00:00:00+00:00https://evan.verworn.ca/posts/the-indie-web/<p>I was reading <a href="https://www.kickscondor.com/on-dat/">KicksCondor</a> post about the
status of Dat.</p>
<p>First, holy hell is that website "out there". Solid unforgettable brutalist
look, I just wish you accommodated the screen size better. Not everyone has a
touchpad or mouse that supports horizontal scrolling, and sometimes I
<strong>prefer</strong> to read on my phone. <a href="https://en.wikipedia.org/wiki/Flush_toilet">Crazy I know.</a>
Support the mobile web yo!</p>
<p>But I totally agree with what he's saying and I too have in the past temporarily
switched to using <a href="https://beakerbrowser.com/">Beaker</a> as my primary personal
driver, coming to similar conclusions. With the addition of discovering that Dat
doesn't work in corporate networks 😞, but IPFS does (showing the
importance of having your service mirrored over 443, as a fallback).</p>
<p>But ignoring all that, what I <em>really</em> wanted to talk about was the crazy list
at the bottom of the post. All of the WebMentions. These were the things missing
in the current implementations of Dat and IPFS. You can't have those. You can't
have that natural growing web of discovery. They are protocols based on
addressing static <em>content</em>.</p>
<p>I had previously dismissed most of <a href="https://indieweb.org/">IndieWeb</a>'s technical
projects as not really contributing or doing much, with the exception of maybe
indieauth or web-sign-in.</p>
<p>I found so many cool websites that I want to follow in reading that one post,
but then I despaired.</p>
<blockquote>
<p>How am I to follow all of these websites.
<span style="float:right">- Foolish Past Evan</span></p>
</blockquote>
<p>The answer is RSS. <span style="float:right">Duh.</span></p>
<p>Then I remembered I don't even have that on <strong>my</strong> own website. Here I am a
person who claims that everyone should have their own domain, host their own
mail and apparently their own voicemail, but not contribute to or believe in
the IndieWeb.</p>
<p>Well consider me embarrassed and impressed, and revisiting my past assumptions.
My goal with this website is now to become an example of what I think other
people should do. Which is be their own social network host.</p>
<aside>
<p>This post was a little scatter-brained, I know. There was just so many thoughts
that I've had and they all surfaced again when I read that blog post on that
weird website.</p>
<p>I've written many things with the intention of posting to this website. But I
always have felt that unless they were edited to a certain degree, I shouldn't
post them. Knowing when to release a product and when to continue working on it,
is an important skill for businesses and groups to know.</p>
<p>But this is my website. I can do whatever the fuck I want.</p>
</aside>
<p>btw, the <a href="https://evan.verworn.ca/feed.xml">feed now exists</a></p>
Getting Lost2019-09-25T00:00:00+00:00https://evan.verworn.ca/posts/getting-lost/<p>A challenge, if you will dear reader. Go out, it doesn't really matter where but
to a place you don't really know. A piece of your local town, a forest you've
never been in, a complicated road system, and become lost.</p>
<p>I recommend doing so at a <abbr title="running, skateboarding, cycling,
driving">speed that is faster than walking</abbr>. As the faster you move the
more concentration it takes, and it will be more difficult to get lost the
slower you move. The more time you have to take in what's around you the more
time you have to remember the way back.</p>
<p>Now "lost" and "stranded" are two different things, and so I recommend you take
your necessary precautions. And while I don't have an issue with you bringing
your phone, it better be off the whole time. The goal is to get into a flow of
movement without hesitation in an unknown space, choosing the path less travelled
and to never stop to make a decision. Getting lost takes time, so don't expect
that 30min be enough time, schedule your being "lost" with ample time.</p>
<p>Now <strong>go</strong>.</p>
My Own Chatroom2019-07-23T00:00:00+00:00https://evan.verworn.ca/posts/my-own-chatroom/<p>Something that I've really wanted was a self-hosted web app built with the
specific purpose of chatting with <strong>me</strong>. I think
<a href="https://lists.sr.ht/~sircmpwn/public-inbox">sircmpwn</a> has been the closest
person to nail it, but <a href="https://discord.gg/W8YXGGJ">discord</a> with their
no-account-required guest accounts and web link invites also come real close.</p>
<aside>
<p>Discord has since made it much harder to use a throwaway guest account with no
email or password associated, but you can still do it.</p>
</aside>
<p>I want to be able to have a service that I can link other people to, and they
can just join, no account required, and it be a real-time chat room. But every
new conversation is viewable and subscribable to me.</p>
<p>Sounds weird in a world where everything is suppose to be e2e encrypted but
imagine with me...</p>
<style>
span[linkish] {
color:var(--accent);
text-decoration: underline;
}
</style>
<p><span linkish="" title="I'm not real... yet.">https://evan.chat/new</span>
that when clicked generates a unique url and saves that to localstorage along
with your user information. Every time you come back, you'll see all the rooms
you've started with an option to start another. If someone else was to visit that
link they would just be let in and they could type whatever username they wanted.</p>
<p>And everything would be viewable/moderated by me.</p>
<p>I could have a <span linkish="" title="still not real.">https://evan.chat/camping-getaway</span> that I
could share with my group of friends who would be coming, it could also expire
after the trip. Everyone would get push-notifications whenever someone talked in
that group, no one needs to signup to a service just for this camping trip, you
just get linked to a chat room and talk.</p>
<p>Private chats would still be available, and whatever you typed would only be
available to users/devices in the room you chose. But I don't think I'd go full
e2e. I think I'd still have the admin user (me) able to read anything. I just
wouldn't want a service I host to be used for illegal purposes that I'm not
aware of. It's <span linkish="">evan.chat</span> after all, privacy is not the
focus, <em>chatting with evan</em> is.</p>
<aside>
<p>I would also love this to not just be over http, but maybe email as well.
<span linkish="">camping-getaway@evan.chat</span> would just be a mailing list that
you could join by sending an email and everything that was said would be synced
both ways.</p>
</aside>
Following Up2019-02-15T00:00:00+00:00https://evan.verworn.ca/posts/voicemail-follow-up/<p>Years ago I wrote about <a href="https://evan.verworn.ca/posts/voicemail">all my problems about voicemail</a>. What I
didn't write about then, was my solution that I made in the following month. This seems to have become a much more popular service that is available since the time I originally wrote that post. And in turn, has encouraged me to write how <em>I</em> solved my problem with voicemail and maybe you can too.</p>
<h2>How We're Going to Solve This</h2>
<ol>
<li>Person calls our phone number and we don't pick up. Call gets forwarded to a number that we choose.</li>
<li>We send our custom greeting.</li>
<li>We listen for what they have to say
<ol>
<li>(Bonus) We take the voice recording and run voice-to-text over it.</li>
</ol>
</li>
<li>We text our cell number with the transcript and attach the recording.</li>
</ol>
<h2>Determining Compatibility</h2>
<p>For this to work you need to change the phone number in your phone that the voicemails get sent to. Normally this is the provider default that gives you the "This person is not available at the moment." For me this was available in my phone app settings under "Voicemail". This might not be available for you to change, in which case you'll have to make a call to your phone provider to change this on their end, or hope that the <a href="https://productioncommunity.publicmobile.ca/t5/Discussions/Voicemail-number-change/td-p/128135">gsm codes</a> work for you.</p>
<h2>Pick your Provider</h2>
<p>I decided to go with <a href="https://twilio.com/">Twilio</a> as my phone provider of choice, for 2 main reasons.</p>
<ol>
<li>At the time, it was the cheapest provider.</li>
<li>It has a voice to text feature.</li>
</ol>
<p>If I were to implement this again, I would even opt for their WhatsApp service as it's cheaper. But for the rest of this post I'm going to be assuming that you're using Twilio.</p>
<h2>Let's Buy a Phone Number</h2>
<p>So in Twilio, you pick your region and can search for any number that is available. You'll want to pick something local to you, so that you don't incur extra charges for the people calling you.</p>
<p>Once we have our number, we can set up webhooks that run when people call or text it.</p>
<p><img src="https://evan.verworn.ca/img/webhooks.png" alt="Twilio Interface">
<small>Pretty self explainitory. When a call comes in, Twilio will send a GET request to that URL.</small></p>
<p>The format of the Twilio request is <a href="https://www.twilio.com/docs/voice">documented well</a>, but in a nut shell we need to return what Twilio should do with this phone call. In this case, play an mp3.</p>
<pre class="language-xml"><code class="language-xml"><span class="highlight-line"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Response</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Play</span><span class="token punctuation">></span></span>https://asdoficzkaljhjhsdf.now.sh/evan.greeting.mp3<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Play</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Record</span> <span class="token attr-name">timeout</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>5<span class="token punctuation">"</span></span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/twilio/end<span class="token punctuation">"</span></span> <span class="token attr-name">transcribeCallback</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/twilio/transcribed<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Say</span> <span class="token attr-name">voice</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>woman<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Please hang up and try again<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Say</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Hangup</span> <span class="token punctuation">/></span></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Response</span><span class="token punctuation">></span></span></span></code></pre>
<p>Breaking this down, Twilio will execute these tasks <em>in order</em> when it recieves a call.</p>
<ul>
<li><code><Play></code> our greeting, this can be any public web url, but make sure that you serve the correct HTTP Headers!</li>
<li><code><Record></code> this will begin recording the conversation <strong>after</strong> the greeting has played. The <code>timeout</code> just means that after 5 seconds of silence (or a hangup) it considers the recording complete.
<ul>
<li>When the message has been recorded, it will send a <code>POST</code> request to the <code>action</code> url with the recorded mp3. This parameter is required.</li>
<li>Additionally after a second or two, the <code>transcribeCallback</code> url will be <code>POST</code>ed to with the transcript of the recorded message. This is really what we want.</li>
</ul>
</li>
<li>The rest <code><Say>...<Hangup/></code> are just there in case my server doesn't return the correct response or times out.</li>
</ul>
<p>So what happens at those two endpoints? Well the required <code>action</code> one is actually trivial, it just returns some XML saying to hangup.</p>
<pre class="language-xml"><code class="language-xml"><span class="highlight-line"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Response</span><span class="token punctuation">></span></span></span><br><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Hangup</span> <span class="token punctuation">/></span></span><span class="token comment"><!-- yup that it --></span></span><br><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Response</span><span class="token punctuation">></span></span></span></code></pre>
<p>The more interesting endpoint is the <code>transcribeCallback</code>. When that's called the request will have the transcription in the body, but also have a link to the recorded mp3.</p>
<p>The below is some of the old code that I use. You can tell because I used <code>var</code>s.</p>
<pre class="language-js"><code class="language-js"><span class="highlight-line">router<span class="token punctuation">.</span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string">'/transcribed'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> <span class="token keyword">var</span> transciption <span class="token operator">=</span> <span class="token string">"<transcription failed>"</span><span class="token punctuation">;</span></span><br><span class="highlight-line"> <span class="token comment">// We can't just use the twilio media url because they</span></span><br><span class="highlight-line"> <span class="token comment">// don't use the correct response headers for .mp3 so</span></span><br><span class="highlight-line"> <span class="token comment">// we have to proxy it.</span></span><br><span class="highlight-line"> <span class="token keyword">var</span> fullRecording <span class="token operator">=</span> req<span class="token punctuation">.</span>body<span class="token punctuation">[</span><span class="token string">'RecordingUrl'</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token string">".mp3"</span><span class="token punctuation">;</span></span><br><span class="highlight-line"> <span class="token keyword">var</span> partial <span class="token operator">=</span> fullRecording<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">api\.twilio\.com\/(.+)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span><br><span class="highlight-line"> <span class="token keyword">var</span> fromNumber <span class="token operator">=</span> req<span class="token punctuation">.</span>body<span class="token punctuation">[</span><span class="token string">'From'</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(?:\+?1)(.+)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span></span><br><span class="highlight-line"> <span class="token keyword">if</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>body<span class="token punctuation">[</span><span class="token string">"TranscriptionStatus"</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token string">"completed"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> transciption <span class="token operator">=</span> req<span class="token punctuation">.</span>body<span class="token punctuation">[</span><span class="token string">"TranscriptionText"</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span><br><span class="highlight-line"> <span class="token punctuation">}</span></span><br><span class="highlight-line"> <span class="token keyword">var</span> client <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'twilio'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>keys<span class="token punctuation">[</span><span class="token string">'ACCOUNT-SID'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> keys<span class="token punctuation">[</span><span class="token string">'AUTH-KEY'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><br><span class="highlight-line"> <span class="token comment">// send a MMS with an attached .mp3</span></span><br><span class="highlight-line"> client<span class="token punctuation">.</span>messages<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span></span><br><span class="highlight-line"> to<span class="token operator">:</span> <span class="token string">"+12895551234"</span><span class="token punctuation">,</span> <span class="token comment">// your voicemail number</span></span><br><span class="highlight-line"> body<span class="token operator">:</span> <span class="token string">"("</span> <span class="token operator">+</span> fromNumber <span class="token operator">+</span> <span class="token string">") "</span> <span class="token operator">+</span> transciption<span class="token punctuation">,</span></span><br><span class="highlight-line"> mediaUrl<span class="token operator">:</span> <span class="token string">'https://asdoficzkaljhjhsdf.now.sh/twilio/download/'</span> <span class="token operator">+</span> partial<span class="token punctuation">,</span></span><br><span class="highlight-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">err<span class="token punctuation">,</span> message</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"SMS Sent."</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><br><span class="highlight-line"> res<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><br><span class="highlight-line"> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><br><span class="highlight-line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span></code></pre>
<p>I think overall pretty straight forward. The only weird part is that we proxy their full mp3 link through our own service, and that's only because they send back a <code>Content-Type: application/octet-stream</code> response header, which their API doesn't like receiving. So I just proxy the request returning <code>Content-Type: audio/mpeg</code> and everything works out.</p>
<p>And really that's it. Now when you call your number, you should hear your greeting, and after leaving a message, be sent a text message with an attached MP3!</p>
<p>First off, if you're following along, Congratulations! You just implemented a service in under 100 lines that knocks the socks off any default phone provider voicemail. Pat yourself on the back.</p>
<h2>How Much Did This Cost Me</h2>
<p>Surprisingly, not much. Assuming you're using <code>now.sh</code> or <code>glitch.io</code> to host your webhooks (which you totally can do). The only thing you have to pay for is Twilio. You'll pay $1/month for the phone number, and 2¢ for sending a text message with a media attachment, and a ¼¢/minute for recording your message and 5¢/minute for the text transcription.</p>
<p>For me, I receive about 10 voicemails a month, at most. So that comes to $1.775/month.</p>
<p>I've had this for about 4 years as of the time of this writing, and I do not regret it at all. This has made receiving phone calls more enjoyable, as now I don't feel obligated to pick up or else have that unclearable voicemail notification. I know that I can silence the call, and after 10 seconds have a text message arrive with a transcript of what was said.</p>
<p>This is a great weekend project that personally I found extremely fulfilling. Now, go forth and kill traditional voicemail!</p>
KeepMe2019-07-26T00:00:00+00:00https://evan.verworn.ca/replies/KeepMe/<p>A fun site to store <a href="https://keepme.io/#/u?k=VTJGc2RHVmtYMS8zbXpNaityWW05Wll2aG9kOG4zL09MMGZnT05ZTnlXM1JnVHFqWVN2ZGVpY3FTK3ZsSVdObE11ZHR6V0hHN05jSVNyckV6TDN3OUZjalRQdEhiNUJGSjFERFEvdkVOSDEwRDFISUxweGFQOTNJNkJBdVk2VDMyREJUbE84KzB3UEVML3pXYzkxV3o4SGxycHZYVXJhWFdBVkpjbUZVbTlBaStOMDJLc0hkMXZ2NDBKNFBualNyUjU0cmw3Sm1TUTBQM0NGTUVQOHhNaVNGbmd6RzVDeU1hblIraG1XZlV5ZktwMFplZ0VLZDhzSVlvN21DaFBzRlZyTEhuejY1ajJSaEhKdHphNDdkYnZRVGJzZEc5QXNBN0hDN3JGYlMxZ3J1T2F5N0JhTUVtL3BpbmQ3SGVpSU1qZmN4M05WZFlIYWh3MWltbS8rWTd3WXVUVmI0clBEOGJFOVI2ZjRWTkpzT0s0MjBDMzk3dTRJU3dzTFZXVWNYVC9uZWQ4djZrZmtjV1hOeXJwMUhEdzRkRFlSZldWQXI2UWxmMjI5L3g3T0dzNjlQanQwYnpXSGlIVGx3eU8rbDBmd3BzVzdBc2xzencrNkszaEFLNHdaSUdhZncwcVFnYXdVMys3cjZhS2xwMno3aDFYWmpkYXBxZEpGRHJvM1M0Q3FIRFhtUEtnU0pxSE5KMnpJQWlHcUNDOU1zWnRBUlg0YWVNL2t4VlpIdW16ZHpuczVvUjJwSmVUZm40NkNhd0xKL1FIcVViTm1HWlozQ01HRC9WalA2VnBSeG00bmtFZzg3TkFaV1QrV2pXTmVGaHZtWTNFaFJtZnNkUWpPS0kzbXVSeEVzVGRxcS9LbDJGQm80VENXZkQxb09ZMTdKdUdORUJPUktJMEY1eE56UWQzYjQzV2lLSisxdHFLdGJmQVJIWmtTRXMyc3NYOFFSYmR6ZW9QakFFOTRCYWgreW5RNzdIS1hKN2pQNUNSWmJPKzFETWtoY3hSRTNpRTJPN3QxMXcvUU02Q2NYdFk1eG1rekhjV1NVQ3RmU085NWh6VE1ocHZDVHk0VzAwYi9LV3QxSUx2SGRtc2VXS21zMA%3D%3D">riddles</a>.</p>
<p>The links get a bit long, and you approach the size limit reeal quick. But you
can do some fun stuff with this.</p>
Fraidycat PSA2019-11-01T00:00:00+00:00https://evan.verworn.ca/replies/Fraidycat/<p>Way to go Kicks! I wish these features were just built into the browser but
you've done the next best thing. Thanks for releasing this and filling that gap!</p>
It's Time to End Voicemail2014-12-11T20:47:02+00:00https://evan.verworn.ca/posts/voicemail/<center>I <i>really</i> hate voicemail.</center>
<p>I don't hate the ability to leave a voice message to a person. Sometimes it's
more human than a text. No, what I really hate is the delivery of that voice
message to my ears. Because it is buried behind a incomprehensibly difficult
usability wall.</p>
<p>Let me show you the conversation that I have to go through every time someone
calls me and I don't pick up.</p>
<ol>
<li>Missed Call from George.</li>
<li>Tap voicemail icon that <strong>refuses</strong> to disappear unless my messages are either "saved"<a href="#footnote-1">[1]</a> or "deleted"</li>
<li>"Please enter your pin"</li>
<li>"You have... 1... new message... Press 1 to listen to your messages... Press 4 to cha~" <em>Press 1</em></li>
<li>"Press 1 to listen to new messages, Press 4 to listen to saved messages" <em>Press 1</em></li>
<li>"New Message from 9...0...5...5...5...5...1...2...3...4...
on... Monday... December 5th at... ten... eleven... pm...</li>
</ol>
<p><em>I'm now waiting with baited breath for what I am sure is going to be a life
changing communique for me to have gone through so many hoops.</em></p>
<p>...Hey Evan it's George, call me back."</p>
<p><strong>Arrr</strong>, in a fury derived from wasting a minute and a half of my time I hang
up. Only to look at my notifications and see that I still have a voicemail.</p>
<p>"What? I have another one?" I think to myself for a fraction of a second. Then I
remember that I didn't hit <strong>7</strong> after my call, thus I will continue to have
that notification until I go back into my voicemail sit through that
computerized woman saying the information extremely slow until it finally
reaches that message <em>again</em> giving me the option to fucking delete it.</p>
<p>I refuse to think we can't do better.</p>
<h2>what the problem is</h2>
<p>Our phone companies haven't needed to innovate. Your phone company controls what
happens if someone rings you and you don't pick up. If you pay your $7-9 dollars
per month, they'll forward you to that <s>infernal</s> helpful computerized woman
prompting the caller to leave a message. (that will never be heard)</p>
<p>If not, they'll be redirected to her anyways but told that "you are unavailable"</p>
<p>Solutions to this problem are beginning to exist. Lately, people like Slack,
Facebook and iOS/Android's Messengers have now allowed sending recorded voice.
Which is better! But not great, because a) they're silos of data that can't talk
to other silos b) people with landlines still exist c) if you already have to
open the texting app, why not <em>just text...</em></p>
<p>You call someone to <strong>make their phone ring</strong>.</p>
<p>You are issuing a "I need to talk to you <strong>right now</strong>" request. And for the
recipient to have to spend 90 seconds to receive that "urgent" message, makes
that message <em>not</em> urgent.</p>
<h2>my solution</h2>
<p>Now with smartphones we have easy control for what happens when someone rings
you and you're not there.</p>
<p>some desperately needed features:</p>
<h4>Full control of the recorded message.</h4>
<p>Just play an mp3 that I give you. Make it <em>stupid</em> simple to change it or record
it on the fly, and don't put anything after it. We don't need a "You can now
leave a message after the beep. When done you can hang up or press pound for
more options."</p>
<h4>Transcription</h4>
<p>If I'm in a meeting and I get a voicemail that the server room is on fire. I'm
not going to know that until <em>after</em> the meeting. But if I'm sent a text right
after with a transcription of a message saying "Holy duck Evan the server room
is on fire." I"ll know to leave the meeting.</p>
<p>Voice to Text still sucks but we've reached the point where you can read the
message and get the gist of it, 90% of the time. Which means that leaving an
urgent voicemail is now <strong>better</strong> than a text. You've made that phone ring, AND
upon the user returning to their phone you've told them that this was important
enough for a call, and provided a summary of the recording. <em>All without
unlocking their phone!</em></p>
<h4>Storage</h4>
<p>We have the technology to store hours of the human voice on a phone, without
impacting their free space. With codecs like <a href="http://speex.org/">Speex</a> we can
put years of voicemails on a phone without the user caring.</p>
<p>30 days then it's gone forever? No More! If you want to keep that awkward first
date request, or grandpa's last voicemail to you forever, you should be able to.</p>
<h4>Cheaper than Netflix</h4>
<p>Paying $7 (or even $6 for iOS voicemail) in 2014 is ridiculous. It should be
costing closer to half that.</p>
<p>If I can <em>stream</em> unlimited amounts of movies from a server in New York for
about the same price as their ancient crappy voicemail. Then either Netflix is
under valuing themselves or phone companies are milking users for as much as
they can.</p>
<p>It costs a buck to reserve a voicemail number, two if you want people to be able
to call it nationwide. 5 cents per message to transcribe it, and basically a
penny a month to store it with 10 cents a month for connecting costs.</p>
<p>For me, I get about 15 voicemails a month, so we're talking 2 bucks and change.
Why the hell am I paying 7?</p>
<h4>Available in the "desolate" country known as CANADA</h4>
<p>Google Voice, would be perfect for me. I'm pretty sure, everyone I know would
want it.</p>
<p>But like their Wallet and Fiber services legal/partnership reasons make it
unviable outside of the US.</p>
<p>We are not Zimbabwe, we are literally touching your border. I sometimes get a
stronger signal from the USA than my own cell provider. COME ON Google, you're
suppose to be the one with deep pockets that we can rely on. Well, you're taking
too long.</p>
<p>It's time for me to do something about it.</p>
<small>
<a name="footnote-1"></a>
[1] I don't know if everyone else has this misunderstanding, but I don't know
the difference between "unread", "read" and "saved". All three of them get
deleted after 30 days.
</small>