After contemplating how complex the implementation of an avatar generator is on one of the most popular Web 2.0 Clouds, I just had to prove how simple it can be on Taubyte (The Web 3.0 Cloud). Besides finding a nice package that generates the avatars, it took me less than 5min to have it live on avatar.examples.tau.link
:
https://avatar.examples.tau.link/goavatar?gender=male&username=fodil.samy
Will generate:
Steps to do the same below.
Getting started
If this is your first time using Taubyte, head to this article for a Quickstart. Otherwise, go ahead and create a new project followed by a new application.
Domain
Make sure you have a domain attached to the application you’ve just created. Refer to “Ping: Your First Serverless Function” if you’re not sure how.
Function
Now that we have everything set up, let’s get to the function itself. If in doubt fall back to “Ping: Your First Serverless Function”.
Code
We’re going to use the “github.com/o1egl/govatar” package to generate the avatars. The exported method GenerateForUsername
takes two arguments: a gender and a username. Diggin into it, I noticed that the generated image depends on the username’s hashed into an integer, which means:
- The same username will result in the same avatar
- A random/changing string will result in the same on the avatar side. This is why you’ll see me using a simple
time.Now()
call to emulate the behavior.
First, declare your package. It does not have to be lib
but we’ll call it a “best practice” as we might make it a naming convention for inline functions later.
package lib
Import all the needed packages:
import (
"bytes"
"strings"
"time"
"bitbucket.org/taubyte/go-sdk/event"
"tinygo.org/x/drivers/image/png"
"github.com/o1egl/govatar"
)
Then, declare your function. Make sure the name in //export
matches the serverless function’s entry point.
//export avatar
func avatarGo(e event.Event) uint32
The function will be triggered by an HTTP event, let’s extract it:
h, err := e.HTTP()
if err != nil {
return 1
}
Our request will look like this:
https://avatar.your.domain.tld/goavatar?gender=<gender>&username=<username>
Use Query().Get()
to extract gender
. We will generate a gender based on time if none is provided.
gender, _ := h.Query().Get("gender")
if gender == "" {
if time.Now().UnixNano()%2 == 0 {
gender = "female"
} else {
gender = "male"
}
}
Do the same for username
. We’ll use the current time as username is none provided.
username, _ := h.Query().Get("username")
if username == "" {
username = time.Now().String()
}
var _gender govatar.Gender
switch strings.ToLower(gender) {
case "male", "m":
_gender = govatar.MALE
case "female", "f":
_gender = govatar.FEMALE
}
Now, let’s now call the GenerateForUsername
. It will return an image.Image
.
img, err := govatar.GenerateForUsername(_gender, username)
if err != nil {
h.Write([]byte("Generate failed with " + err.Error()))
return 1
}
Finally, we convert the image into a PNG that we send to the client.
var b bytes.Buffer
err = png.Encode(&b, img)
if err != nil {
h.Write([]byte("PNG Encoding failed with " + err.Error()))
return 1
}
h.Headers().Set("Content-Type", "image/png")
h.Write(b.Bytes())
Commit and Push
At this point, everything is happening inside a virtual file system hosting your repo on your browser. To make the network aware of your changes, you need to push them to Github.
Builds
Check that the build for both configuration and the function’s code went through.
Test it
Navigate to https://avatar.your.domain.tld/goavatar
(don’t forget to set your username)