您如何向潜在客户和现有客户教授技术性很强的主题?如何让旅途顺利?
在 Isovalent,我们热衷于为用户提供尽可能无缝的学习体验。 Isovalent 是 Cilium 的创建者,Cilium 是事实上的 Kubernetes 云网络平台。虽然我们热爱网络和安全,但我们很高兴人们可能会觉得这是一个困难的话题。我们认为我们会让学习 Kubernetes 网络变得有趣,因此我们将学习体验游戏化。
Instruqt 提供了一个很棒的平台来构建实践实验室,该实验室既具有先进的技术,又对用户有吸引力。
我们还相信用户体验应该流畅并且流程应该完全自动化。
幸运的是,利用 Instruqt graphQL API 可以做很多事情。
为此,我们编写了自己的 instruqt-go 库,并决定将其开源。该库旨在帮助开发人员轻松实现自动化并与 Instruqt 平台集成。
发布 Instruqt 实验室的问题之一是将 Instruqt 中的用户信息与您自己的数据库或 CRM 的用户信息链接起来。
在第一篇文章中,我们将指导您使用 instruqt-go 构建代理:
然后我们将在 Google Cloud Functions 上发布该函数。
在实验室收集用户信息的原因有多种:
有多种方法可以将用户数据传递到 Instruqt 轨道。
Instruqt 自定义参数对于在启动曲目时传递任何类型的信息非常有用。这些字段只是作为查询参数添加到 URL,并以 icp_ 为前缀。这些参数还可以在 Instruqt webhooks 以及 Instruqt GraphQL API 中检索,使其实用起来。
直到最近,Instruqt 还鼓励赛道开发人员使用自定义参数传递用户信息(例如姓名、电子邮件或令牌)。
但是,使用自定义参数有一些缺点:
Instruqt 邀请允许创建曲目列表并生成可与用户共享以便于访问的邀请链接。邀请可以设置为通过表单收集用户数据。
然后,此用户数据将添加到 Instruqt 上的用户详细信息中(用户详细信息附加到用户帐户,但每个 Instruqt 团队都是唯一的)。
这对于研讨会来说非常实用,但也有一些限制:
注意:Instruqt 最近推出了登陆页面,这是一种邀请形式,可以调整登陆页面,具有相同的优点和限制。
最近,Instruqt 添加了另一种传递用户信息的方式,它结合了之前两种方法的优点。
加密的 PII 方法允许将 pii_tpg 查询参数传递到嵌入 URL。这意味着:
我们将在本例中使用这种新方法,因为它是当今最通用的以安全可靠的方式向 Instruqt 传递信息的方法。
当您访问 Instruqt 上的曲目页面时,可以选择嵌入曲目。
这将为您提供一个 URL,其中包含该曲目独有的令牌。
虽然使用该 URL 是完全有效的,但这也意味着任何有权访问此令牌的人都可以随时开始曲目。
Instruqt 最近添加了一个 API 调用来为曲目生成一次性令牌,这样使用此类令牌的 URL 只能使用一次。
我们正在编码的代理将使用一次性令牌,因为我们可以访问 API 并且可以轻松生成它们。
首先,为您的函数创建一个目录:
mkdir instruqt-proxy
移动到该目录并初始化Go环境:
# Replace example.com with the prefix of your choice go mod init example.com/labs
对于本地测试,创建一个cmd目录:
mkdir cmd
在该目录中创建一个 main.go 文件,内容如下:
package main import ( "log" "os" // Blank-import the function package so the init() runs // Adapt if you replaced example.com earlier _ "example.com/labs" "github.com/GoogleCloudPlatform/functions-framework-go/funcframework" ) func main() { // Use PORT environment variable, or default to 8080. port := "8080" if envPort := os.Getenv("PORT"); envPort != "" { port = envPort } if err := funcframework.Start(port); err != nil { log.Fatalf("funcframework.Start: %v\n", err) } }
返回 instruqt-proxy 目录,创建一个 proxy.go 文件,然后向其中添加 init() 函数以及我们将使用的 Go 包:
package labs import ( "fmt" "net/http" "net/url" "os" "github.com/GoogleCloudPlatform/functions-framework-go/functions" "github.com/isovalent/instruqt-go/instruqt" ) func init() { functions.HTTP("InstruqtProxy", instruqtProxy) }
这将允许 Google Cloud Functions 在初始化时调用 instruqtProxy 函数。
让我们编写该函数:
const ( // Replace team name with yours instruqtTeam = "isovalent" ) func instruqtProxy(w http.ResponseWriter, r *http.Request) { instruqtToken := os.Getenv("INSTRUQT_TOKEN") if instruqtToken == "" { w.WriteHeader(http.StatusInternalServerError) return } instruqtClient := instruqt.NewClient(instruqtToken, instruqtTeam) // Get user from passed token utk := r.URL.Query().Get("utk") if utk == "" { w.WriteHeader(http.StatusUnauthorized) return } user, err := getUser(utk) if err != nil { w.WriteHeader(http.StatusUnauthorized) return } labSlug := r.URL.Query().Get("slug") url, err := getLabURL(instruqtClient, user, labSlug) if err != nil { w.WriteHeader(http.StatusNotFound) return } http.Redirect(w, r, url, http.StatusFound) }
在此函数中,我们:
getLabURL 函数将根据用户信息、请求的实验室 slug 以及来自 Instruqt API 的动态信息生成实验室的重定向 URL。
我们来写吧:
const ( // Replace with your sign-up page format labSignupPage = "https://isovalent.com/labs/%s" // Adapt to your values finishBtnText = "Try your next Lab!" finishBtnURL = "https://labs-map.isovalent.com/map?lab=%s&showInfo=true" ) func getLabURL(instruqtClient *instruqt.Client, u user, slug string) (string, error) { track, err := instruqtClient.GetTrackBySlug(slug) if err != nil { return "", err } // Unknown user if u.Email == "" { url := fmt.Sprintf(labSignupPage, slug) return url, nil } // Get one-time token token, err := instruqtClient.GenerateOneTimePlayToken(track.Id) if err != nil { return "", err } labURL, err := url.Parse(fmt.Sprintf("https://play.instruqt.com/embed/%s/tracks/%s", instruqtTeam, track.Slug)) if err != nil { return "", err } // Prepare the fields to encrypt encryptedPII, err := instruqtClient.EncryptUserPII(u.FirstName, u.LastName, u.Email) if err != nil { return "", err } // Add params params := map[string]string{ "token": token, "pii_tpg": encryptedPII, "show_challenges": "true", "finish_btn_target": "_blank", "finish_btn_text": finishBtnText, "finish_btn_url": fmt.Sprintf(finishBtnURL, track.Slug), } q := labURL.Query() for key, value := range params { q.Set(key, value) } // Encode the parameters labURL.RawQuery = q.Encode() return labURL.String(), nil }
首先,请注意,我们定义了一些您可以调整的新常量:
现在我们来解释一下getLabURL()函数的步骤:
此代理中缺少的最后一个部分是 getUser() 函数。我在这里帮不了你太多,因为这部分是你插入你自己的逻辑的地方。您可能正在使用像 Hubspot 这样的 CRM 从 UTK 或其他数据库检索联系信息,这取决于您!
我将在此处向您展示的代码仅返回示例用户:
/* * This is where you add the logic to get user information from your CRM/database. */ type user struct { FirstName string LastName string Email string } func getUser(utk string) (u user, err error) { // Implement the logic to get your user information from UTK u = user{ FirstName: "John", LastName: "Doe", Email: "john@doe.com", } return u, err }
现在我们已经有了完整的 proxy.go 功能,让我们测试一下!
首先,使用以下内容更新您的 go.mod 和 go.sum 文件:
go get ./... go mod tidy
在 Instruqt 仪表板中,转到“API 密钥”并获取 API 密钥的值。将其导出为 shell 中的变量:
export INSTRUQT_TOKEN=<your_instruqt_token>
接下来,在本地计算机上启动该功能:
FUNCTION_TARGET=InstruqtProxy go run ./cmd/main.go
最后,在另一个终端中,向 localhost:8080 发出测试请求,您的函数将在其中运行(如果需要,您可以传递上面的 PORT 环境变量来更改端口):
curl -i "localhost:8080/?slug=cilium-getting-started&utk=someUtkValue"
适应使用 Instruqt 组织中存在的轨道 slug。如果该曲目存在,您应该会收到一个 302 响应,其中包含用于访问的一次性令牌的重定向 URL,以及使用 PII 密钥加密的 John Doe 的信息和一次性令牌(以 ott_ 开头)!
如果您想使用 Docker 在本地测试您的功能,您可以在当前目录中创建一个 Dockerfile:
FROM golang:1.23 WORKDIR /app COPY . . RUN go build -o myapp ./cmd/main.go ENV DEV=true ENV PORT=8080 EXPOSE $PORT CMD ["./myapp"]
添加 docker-compose.yaml 文件:
version: '3' services: proxy: build: ./ ports: - "8080:8080" environment: INSTRUQT_TOKEN: ${INSTRUQT_TOKEN} FUNCTION_TARGET: InstruqtProxy
最后,构建并启动您的容器:
docker-compose up --build
并且您可以像以前一样向 localhost:8080 发送请求!
In order to deploy to Google Cloud, first make sure you are logged in to your Google Cloud project:
gcloud auth application-default login
Next, let's create a new secret for the Instruqt token:
echo -n "$INSTRUQT_TOKEN" | gcloud secrets create instruqt-token --data-file=-
In order to adjust the permissions on this secret, you will need to get your project ID:
PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value project) --format="value(projectNumber)")
Then, add the "Secret Manager Secret Accessor" role for the default Compute Engine service account for the project:
gcloud secrets add-iam-policy-binding instruqt-token \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor"
Your secret is now ready to be used by the function!
You can then deploy the function (adapt the region if needed):
gcloud functions deploy "instruqt-proxy" \ --gen2 --runtime=go122 --region=europe-west1 --source=. \ --entry-point="InstruqtProxy" --trigger-http --allow-unauthenticated \ --set-secrets="INSTRUQT_TOKEN=instruqt-token:latest"
This will upload and build your project, and return the URL to access the function.
This URL will look something like https://europe-west1-
You can then test the function using that URL instead of localhost:8080!
This is a simplified approach to the lab proxy we use at Isovalent. There are things you might want to consider with this implementation:
This proxy can typically be used to give access to authenticated users in a safe way, while preserving user information in Instruqt reports and making sure embed URLs are not reusable.
Here is an example of usage of this proxy:
This can allow you to build a series of public sign-up pages for your labs, similar to what we have built on the Isovalent website. It can also be used to build a Kiosk interface, or even a more creative landing page such as the Cilium Labs map, where clicks on the map redirect to the lab proxy.
By making a complex networking technology like Cilium fun with our labs, we have made it the experience for users less intimidating and more approachable. Using our proxy can help you provide a similar user experience to your prospects. Please get in touch if you have any questions.
以上是简化对嵌入式 Instruqt 实验室的访问的详细内容。更多信息请关注PHP中文网其他相关文章!