Stencil Documentation
  • General
  • API
    • Authentication
      • Account
    • Pagination
    • Status Code and Throttling
    • Endpoints
      • Projects
      • Templates
      • Images
      • Collections
      • PDFs
      • Airtable
    • Charts
  • Using Stencil
    • Template Editor (New)
    • Template Editor (Legacy)
      • Limited Markdown Supports
      • Anchoring Element
      • Using Custom Font
      • Circular Text Positioning
    • White Label for Business
      • Setting Up Your First Client
      • DNS Setup with Cloudflare
  • Guides
    • Airtable Integration
      • Basic
    • Integromat Integration
      • Connection
      • Instant Trigger
    • Zapier Integration
      • Authentication
      • Trigger - New Image
      • Action - Create Image
    • Secure Signed Image
      • Basic
    • Query String Integration
      • Basic
      • Cache
    • Forms Integration
    • Case Studies
      • Generate Instagram Post from WooCommerce
      • Generate Open Graph Image for WordPress
      • Generate Personalized SendGrid Email Campaigns
      • Sending Charts to Twitter
      • Generate Instagram Post from Shopify
      • Automating Webflow Open Graph Image
      • Generate certificate of accomplishment
      • Automate Candidate's Certificate Generation
  • LINKS
    • Back to Stencil
    • Got bug?
    • Need feature?
    • Blog
Powered by GitBook
On this page
  • Case study
  • Guides
  • Design your certificate template
  • Creating Signed URL for Image
  • Result
  • Determining authenticity
  • No-code URL generation
  • 1. AWS Lambda
  • 2. Airtable
  • 3. Google Sheet

Was this helpful?

  1. Guides
  2. Case Studies

Generate certificate of accomplishment

PreviousAutomating Webflow Open Graph ImageNextAutomate Candidate's Certificate Generation

Last updated 3 years ago

Was this helpful?

Case study

Often time, course participants will receive their certificate of accomplishment digitally and they can link the image of the certificate in their social profile network like LinkedIn.

If you are running these courses and would like to provide such certificate there are few things that you need to handle.

First, generating the certificate image itself. Then, most importantly ensuring certificate authenticity. Since the image can be doctored digitally, you need to employ your own system to handle certificate validation.

Stencil's secured signed image can solve these issues and you'll see how we can this is handled. Of course, in some complicated cases you would still need to roll your own system but for the majority of the time, this is sufficient.

Guides

Design your certificate template

For this design, candidate's name can be customized later using our API.

Creating Signed URL for Image

Getting the necessary information

You'll need some information that can be retrieved from Console > Integrations > Secure Signed Image

Generate the URL

For example this is the Python code we use with the certificate template that was created from previous step.

import json
import hmac
import hashlib
import base64

def base64_encode(string):
    """
    Removes any `=` used as padding from the encoded string.
    """
    encoded = base64.b64encode(string.encode())
    encoded = encoded.rstrip(b'=')
    return encoded

def generate_url():
  user_id = "be6a052e-bce8-4c14-8bbb-ea6b6f9941d5"
  secret_key = "secretzzzz"
  base_id = "TEafv3AfNptmzii4zj2jkc"

  modifications = [
    { "name": "text_candidate", "text": "John Wick" }
  ]

  # ensure no spaces in json output
  encoded = json.dumps(modifications, separators=(',', ':'))
  encoded = base64_encode(encoded).decode()

  parameters = "{user_id}+{base_id}+{modifications}".format(user_id=user_id, base_id=base_id, modifications=encoded)

  signature = hmac.new(secret_key.encode(), parameters.encode(), hashlib.sha256).hexdigest()

  url = "https://images.usestencil.com/signed-images/{user_id}/{base_id}.png?modifications={modifications}&s={signature}".format(
      base_id=base_id,
      user_id=user_id,
      modifications=encoded,
      signature=signature
  )
  print(url)

if __name__ == "__main__":
    generate_url()

Running the above code gives us the following output,

https://images.usestencil.com/signed-images/be6a052e-bce8-4c14-8bbb-ea6b6f9941d5/TEafv3AfNptmzii4zj2jkc.png?modifications=W3sibmFtZSI6InRleHRfY2FuZGlkYXRlIiwidGV4dCI6IkpvaG4gV2ljayJ9XQ&s=f69736c6f17cea118a45dc018103694cbde78d89513de977c2fa1c55faf697df

Result

Visiting the URL gives us the certificate,

Determining authenticity

All certificates generated and hot-linked using our CDN can be considered as authentic i.e. all links started with https://images.usestencil.com/signed-images/... are authentic.

Why?

TLDR

All images are signed with your secret key. Trying to modify the data will invalidate the signature.

Continue reading to know the details.

Let's break it down. The URL can be broken down to several parts,

Item

Description

https://images.usestencil.com/signed-images/be6a052e-bce8-4c14-8bbb-ea6b6f9941d5/TEafv3AfNptmzii4zj2jkc.png

This is the base URL

modifications=W3sibmFtZSI6InRleHRfY2FuZGlkYXRlIiwidGV4dCI6IkpvaG4gV2ljayJ9XQ

Base64 encoded modifications

s=f69736c6f17cea118a45dc018103694cbde78d89513de977c2fa1c55faf697df

Signature that we use to determine the authenticity of the request

If we decode the base64 modifications, we will get the following output,

[{"name":"text_candidate","text":"John Wick"}]

You might think, "Hey what if I modify the value and encode it back. That should work, right?"

Let's just do that. We changed the value to John the Impostor and got back the following base64 encoded string.

[{"name":"text_candidate","text":"John the Impostor"}]

W3sibmFtZSI6InRleHRfY2FuZGlkYXRlIiwidGV4dCI6IkpvaG4gdGhlIEltcG9zdG9yIn1d

Putting everything together we get back,

https://images.usestencil.com/signed-images/be6a052e-bce8-4c14-8bbb-ea6b6f9941d5/TEafv3AfNptmzii4zj2jkc.png?modifications=W3sibmFtZSI6InRleHRfY2FuZGlkYXRlIiwidGV4dCI6IkpvaG4gdGhlIEltcG9zdG9yIn1d&s=f69736c6f17cea118a45dc018103694cbde78d89513de977c2fa1c55faf697df

Visiting the URL gave us the following image instead,

If you look at the response header, you should see the following header

x-stencil-error: Invalid signature

The reason is that, the signature doesn't contain the right modifications and thus rejected by our server. By ensuring the image is signed with our secret key, we can ensure image authenticity. Simple, right?

No-code URL generation

As you can see, we have to run one Python script to generate the link for our certificate. There are few things we can do so that we don't have to run the Python script each time. Here are few options you can explore to do this.

1. AWS Lambda

You can modify the Python script as a lambda function that accepts the candidate's name and when run, it will return the generated URL.

You can then combine this with other tools such as Airtable where you can input list of names, and use any automation services like Zapier, Integromat, UiPath and others to run the lambda function when your Airtable rows are added/updated and update the corresponding rows with the generated link.

2. Airtable

Airtable has scripting ability and you can write a similar script to generate the link.

3. Google Sheet

Google Sheet also has scripting ability and you can write a similar script to generate the link.

There are numerous of ways to do this and these are just some of them.

The section explains how the URL is generated. We can use the Python code provided and modifying it based on the information we get. We also need to specify the proper modifications that will be sent to our API.

We have created a guide utilizing AWS Lambda for this. You can find it

Basic
here
AWS-like certificate
Information required in the next step
Signed image with candidate's name
Invalid image