小程序分享
简介
该 Codelabs 将聚焦在如何通过转发链接、图文、分享口令等不同形式分享小程序。
能力介绍
分享是指由用户主动触发,指定小程序落地页,分享至抖音私信或其他端外场景,引导其他用户回流至小程序。
同时支持多种分享方式,例如卡片、短链、图文等,由用户根据喜好选择分享方式。
注:端外场景回流至小程序需经过用户二次确认。
如何设置分享素材
目标
分享到私信:
分享到外部渠道:
调用方式
前提条件
学习内容
- •如何创建分享模板
- •如何配置分享页面
- •如何获取服务端分享链接
创建分享模板
你需要在抖音开放平台预先创建分享模板,包含需要分享的图片、标题、文案,并提交平台进行审核。
平台审核通过后再使用对应的分享模板 ID 配置到页面转发参数中。
创建分享模板步骤如下:
- 1.登录抖音开放平台控制台,进入小程序应用详情页。
- 2.在左侧导航栏选择「运营」>「流量配置」,在「流量配置」页面「全部」页签点击「分享设置」。
- 3.在「分享设置」页面填写「分享标题」、「分享文案」和「分享图案」,然后点击「提交审核」。
- 4.提交审核后,可以看到如下界面。
- 5.在审核通过后,就可以在小程序代码内使用上图中的分享 ID了。
接下来,就可以使用对应的分享 ID 来配置分享页面了。
配置分享页面
本页目标
开发者能够对小程序的分享流程和入口有概念,并且能够实现对应的功能。
小程序内的分享流程
如下图所示,页面分享的入口是 button 按钮、页面右上角的「更多面板—分享」和截图分享。
之后由用户在分享面板中选择各种分享渠道,包括抖音消息、微信、朋友圈、链接分享等。
小程序内的分享入口
根据规范,小程序的分享必须由用户触发,不能由开发者主动调用。
当前小程序内的分享入口有下面三种。
入口 | 触发方式 | 效果 | 特殊说明 |
button 组件 | 自定义按钮 <button open-type="share">点击完成小程序分享button> | | |
更多面板-分享 | 点击小程序右上角的「更多面板—分享」按钮,触发小程序的分享。 | | |
截图分享 | 用户主动截图 | |
分享配置
- •函数入参:当用户点击分享按钮、页面右上角的「更多面板—分享」或触发截图分享时,onShareAppMessage 会被触发,接收来自用户点击「分享入口」时传入的参数 ShareOption。
- •函数返回值: onShareAppMessage 函数返回的数据格式可以参照 ShareParam,其中 templateId 就是我们上一节中在开发者后台申请的分享模版ID。
转发链接增加自定义参数
- •在 ShareParam 的 path 参数中可以添加相关 query
- •转发页面打开时,query参数会传入 onload 方法
Page({ onShareAppMessage(shareOption) { return { // 分享地址,未填则默认分享当前页面 // ?后面的参数会在转发页面打开时传入onLoad方法 path: `/pages/component/button/button?from=${shareOption.from}&isShare=true`, templateId: "3h8i11h04d3g40njx3", title: "页面传入的分享标题", success() { console.log("分享面板调起成功,不代表分享成功"); }, fail(e) { console.log("分享面板调起失败", e); }, }; }, onLoad(query) { if (query.isShare) { console.log(`来自分享入口:${query.from}打开`); } }, });
Demo 工程
效果展示
用户点击页面按钮分享到抖音私信
用户点击页面按钮分享到微信/朋友圈
用户选择链接形式分享
服务端获取分享链接
获取票据
{appid} 替换为对应的小程序 id,操作位置如下图所示:
在调用所有小程序 OpenAPI 时,需要通过 getAccesstoken 接口进行票据认证,调用方式如下:
Go
type TokenRequest struct { Appid string Secret string } type TokenResponseData struct { AccessToken string `json:"access_token"` } type TokenResponse struct { ErrNo int64 `json:"err_no"` ErrTips string `json:"err_tips"` Data TokenResponseData `json:"data"` } func Get(appid string, secret string) string { url := "https://developer.toutiao.com/api/apps/v2/token" method := "POST" reqMap := make(map[string]string) reqMap["secret"] = secret reqMap["appid"] = appid reqMap["grand_type"] = "client_credential" reqMap["grant_type"] = "client_credential" reqBody, _ := json.Marshal(reqMap) payload := strings.NewReader(string(reqBody)) client := &http.Client{} req, err := http.NewRequest(method, url, payload) if err != nil { fmt.Println(err) return "" } req.Header.Add("Content-Type", "application/json") res, err := client.Do(req) if err != nil { fmt.Println(err) return "" } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println(err) return "" } fmt.Println(string(body)) respBody := TokenResponse{} _ = json.Unmarshal(body, &respBody) if respBody.ErrNo == 0 { return respBody.Data.AccessToken } else { return "" } }
Java
// java import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import okhttp3.*; public class AccessToken { public static String Get(String appid, String secret) throws Exception { OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); AccessTokenRequest accessTokenRequest = new AccessTokenRequest(appid, secret); Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create(); String accessTokenRequestString = gson.toJson(accessTokenRequest); RequestBody body = RequestBody.create(mediaType, accessTokenRequestString); Request request = new Request.Builder() .url("https://developer.toutiao.com/api/apps/v2/token") .method("POST", body) .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); if (response.code() != 200) { return ""; } ResponseBody responseBody = response.body(); if (responseBody != null) { String responseString = responseBody.string(); AccessTokenResponse accessTokenResponse = gson.fromJson(responseString, AccessTokenResponse.class); if (accessTokenResponse.getErrNo() != 0) { return ""; } return accessTokenResponse.getData().getToken(); } return ""; } } public class AccessTokenRequest { @SerializedName("appid") private String appId; @SerializedName("secret") private String secret; @SerializedName("grand_type") private String GrandType = "client_credential"; @SerializedName("grant_type") private String GrantType = "client_credential"; public AccessTokenRequest(String appId, String secret) { this.appId = appId; this.secret = secret; } public String getAppId() { return appId; } public void setAppId(String appId) { this.appId = appId; } public String getSecret() { return secret; } public void setSecret(String secret) { this.secret = secret; } } public class AccessTokenResponse { @SerializedName("err_no") private long errNo; @SerializedName("err_tips") private String errTips; @SerializedName("data") private TokenData data; public AccessTokenResponse(long errNo, String errTips, TokenData data) { this.errNo = errNo; this.errTips = errTips; this.data = data; } public long getErrNo() { return errNo; } public void setErrNo(long errNo) { this.errNo = errNo; } public String getErrTips() { return errTips; } public void setErrTips(String errTips) { this.errTips = errTips; } public TokenData getData() { return data; } public void setData(TokenData data) { this.data = data; } } public class TokenData { @SerializedName("access_token") private String token; public TokenData(String token) { this.token = token; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } }
JavaScript
const axios = require('axios'); module.exports = function getAccessToken(appId,secret) { const config = { method: 'post', url: 'https://developer.toutiao.com/api/apps/v2/token', headers: { 'Content-Type': 'application/json', "Accept-Encoding": "*" }, data: { secret, grant_type: "client_credential", grand_type: "client_credential", appid: appId } }; return axios(config) .then(function (response) { if(response.data && response.data.err_no === 0 ){ return response.data.data.access_token; }else{ throw new Error('accessToken获取失败:'+ response.data && response.data.err_tips); } }) }
分享二维码
通过链接传参,生成图片二进制数据,开发者自行存储。
Go
type RGB struct { RValue uint8 `json:"r"` GValue uint8 `json:"g"` BValue uint8 `json:"b"` } type CreateRequest struct { AccessToken string `json:"access_token"` AppName string `json:"appname"` Path string `json:"path"` Width uint `json:"width"` LineColor *RGB `json:"line_color"` BackGroundColor *RGB `json:"background"` SetIcon bool `json:"set_icon"` } func CreateQrcode(token string, appName string, path string, width uint, lineColor *RGB, background *RGB, setIcon bool) []byte { url := "https://developer.toutiao.com/api/apps/qrcode" method := "POST" qrcodeRequest := &CreateRequest{ AccessToken: token, AppName: appName, Path: path, Width: width, LineColor: lineColor, BackGroundColor: background, SetIcon: setIcon, } requestBody, _ := json.Marshal(qrcodeRequest) payload := strings.NewReader(string(requestBody)) client := &http.Client{} req, err := http.NewRequest(method, url, payload) if err != nil { fmt.Println(err) return nil } req.Header.Add("Content-Type", "application/json") res, err := client.Do(req) if err != nil { fmt.Println(err) return nil } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println(err) return nil } fmt.Println(string(body)) return body }
Java
// java import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import okhttp3.*; import toutiao.accesstoken.AccessTokenResponse; public class QrCode { public static byte[] Create(QrCodeRequest qrCodeRequest) throws Exception { Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create(); OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create( mediaType, gson.toJson(qrCodeRequest)); Request request = new Request.Builder() .url("https://developer.toutiao.com/api/apps/qrcode") .method("POST", body) .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); if (response.code() != 200) { return null; } ResponseBody responseBody = response.body(); if (responseBody != null) { return responseBody.bytes(); } return null; } } public class QrCodeRequest { @SerializedName("access_token") private String accessToken; @SerializedName("appname") private String appName; @SerializedName("path") private String path; @SerializedName("width") private int width; @SerializedName("line_color") private RgbEntity lineColor; @SerializedName("background") private RgbEntity backGround; @SerializedName("set_icon") private boolean setIcon; public QrCodeRequest(String accessToken, String appName, String path, int width, RgbEntity lineColor, RgbEntity backGround, boolean setIcon) { this.accessToken = accessToken; this.appName = appName; this.path = path; this.width = width; this.lineColor = lineColor; this.backGround = backGround; this.setIcon = setIcon; } public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public RgbEntity getLineColor() { return lineColor; } public void setLineColor(RgbEntity lineColor) { this.lineColor = lineColor; } public RgbEntity getBackGround() { return backGround; } public void setBackGround(RgbEntity backGround) { this.backGround = backGround; } public boolean isSetIcon() { return setIcon; } public void setSetIcon(boolean setIcon) { this.setIcon = setIcon; } } public class RgbEntity { @SerializedName("r") private int RValue; @SerializedName("g") int GValue; @SerializedName("b") int BValue; public int getRValue() { return RValue; } public void setRValue(int RValue) { this.RValue = RValue; } public int getGValue() { return GValue; } public void setGValue(int GValue) { this.GValue = GValue; } public int getBValue() { return BValue; } public void setBValue(int BValue) { this.BValue = BValue; } }
JavaScript
const axios = require('axios'); module.exports = function createQrCode(accessToken,{ path, width, lineColor, background }) { var config = { method: 'post', url: 'https://developer.toutiao.com/api/apps/qrcode', headers: { 'Content-Type': 'application/json', }, responseType:"arraybuffer", data: { appname: "douyin", access_token: accessToken, path, width:width || 1000, line_color: lineColor || { "r": 0, "g": 0, "b": 0 }, background:background || { "r": 255, "g": 255, "b": 255 }, set_icon: false } }; return axios(config) .then(function (response) { if(!response.data || response.data.errmsg){ throw new Error('二维码生成失败:'+response.data.errmsg); } return response.data; }); }
生成分享链接
根据传递的链接参数,生成小程序跳转分享链接。
Go
type LinkGenerateReq struct { AccessToken string `json:"access_token"` AppName string `json:"app_name"` AppId string `json:"ma_app_id"` Path string `json:"path"` Query string `json:"query"` ExpireTime int64 `json:"expire_time"` } type LinkGenerateResp struct { ErrorCode int64 `json:"err_no"` ErrorTips string `json:"err_tips"` URLLink string `json:"url_link"` } func Generate(token string, appName string, appid string, path string, query string, expireTime int64) string { url := "https://developer.toutiao.com/api/apps/url_link/generate" method := "POST" reqStruct := &LinkGenerateReq{ AccessToken: token, AppName: appName, AppId: appid, Path: path, Query: query, ExpireTime: expireTime, } reqBody, _ := json.Marshal(reqStruct) payload := strings.NewReader(string(reqBody)) client := &http.Client{} req, err := http.NewRequest(method, url, payload) if err != nil { fmt.Println(err) return "" } req.Header.Add("Content-Type", "application/json") res, err := client.Do(req) if err != nil { fmt.Println(err) return "" } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println(err) return "" } fmt.Println(string(body)) respStruct := &LinkGenerateResp{} _ = json.Unmarshal(body, respStruct) if respStruct.ErrorCode == 0 { return respStruct.URLLink } else { return "" } }
Java
// java import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import okhttp3.*; public class Generate { public static GenerateResponse Generate(GenerateRequest generateRequest) throws Exception { OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create(); RequestBody body = RequestBody.create( mediaType, gson.toJson(generateRequest)); Request request = new Request.Builder() .url("https://developer.toutiao.com/api/apps/url_link/generate") .method("POST", body) .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); if (response.code() != 200) { return null; } ResponseBody responseBody = response.body(); if (responseBody == null) { return null; } String result = responseBody.string(); return gson.fromJson(result, GenerateResponse.class); } } public class GenerateRequest { @SerializedName("access_token") private String accessToken; @SerializedName("app_name") private String appName; @SerializedName("ma_app_id") private String appId; @SerializedName("path") private String path; @SerializedName("query") private String query; @SerializedName("expire_time") private long expireTime; public GenerateRequest(String accessToken, String appName, String appId, String path, String query, long expireTime) { this.accessToken = accessToken; this.appName = appName; this.appId = appId; this.path = path; this.query = query; this.expireTime = expireTime; } public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } public String getAppId() { return appId; } public void setAppId(String appId) { this.appId = appId; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getQuery() { return query; } public void setQuery(String query) { this.query = query; } public long getExpireTime() { return expireTime; } public void setExpireTime(long expireTime) { this.expireTime = expireTime; } } public class GenerateResponse { @SerializedName("err_no") private long errNo; @SerializedName("err_tips") private String errTips; @SerializedName("url_link") private String urlLink; public GenerateResponse(long errNo, String errTips, String urlLink) { this.errNo = errNo; this.errTips = errTips; this.urlLink = urlLink; } public long getErrNo() { return errNo; } public void setErrNo(long errNo) { this.errNo = errNo; } public String getErrTips() { return errTips; } public void setErrTips(String errTips) { this.errTips = errTips; } public String getUrlLink() { return urlLink; } public void setUrlLink(String urlLink) { this.urlLink = urlLink; } }
JavaScript
const axios = require('axios'); function generateUrlLink(accessToken, appId, { query, path, expireTime }) { var config = { method: 'post', url: 'https://developer.toutiao.com/api/apps/url_link/generate', headers: { 'Content-Type': 'application/json' }, data : { access_token:accessToken, ma_app_id:appId, app_name:"douyin", path, query, expire_time: expireTime } }; return axios(config) .then(function (response) { if(response.data && response.data.err_no === 0){ return response.data.url_link; } throw new Error('生成urlink失败:'+ response.data && response.data.err_tips) }); }
查询链接基本信息
根据小程序分享链接,查询相关链接的基本信息。
Go
type LinkInfo struct { AppName string `json:"app_name"` AppId string `json:"ma_app_id"` Path string `json:"path"` Query string `json:"query"` CreateTime int64 `json:"create_time"` ExpireTime int64 `json:"expire_time"` } type LinkQueryInfoReq struct { AccessToken string `json:"access_token" mask:"session"` MaAppId string `json:"ma_app_id"` URLLink string `json:"url_link"` } type LinkQueryInfoResp struct { ErrorCode int64 `json:"err_no"` ErrorTips string `json:"err_tips"` URLLinkInfo LinkInfo `json:"url_link_info"` } func QueryInfo(token string, urlLink string, appid string) { url := "https://developer.toutiao.com/api/apps/url_link/query_info" method := "POST" reqStruct := &LinkQueryInfoReq{ AccessToken: token, MaAppId: appid, URLLink: urlLink, } reqBody, _ := json.Marshal(reqStruct) payload := strings.NewReader(string(reqBody)) client := &http.Client{} req, err := http.NewRequest(method, url, payload) if err != nil { fmt.Println(err) return } req.Header.Add("Content-Type", "application/json") res, err := client.Do(req) if err != nil { fmt.Println(err) return } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println(err) return } fmt.Println(string(body)) }
Java
// java import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import okhttp3.*; import toutiao.accesstoken.AccessTokenResponse; public class QueryInfo { public static QueryInfoResponse QueryInfo(QueryInfoRequest queryInfoRequest) throws Exception { OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create(); String queryInfoRequestString = gson.toJson(queryInfoRequest); RequestBody body = RequestBody.create(mediaType, queryInfoRequestString); Request request = new Request.Builder() .url("https://developer.toutiao.com/api/apps/url_link/query_info") .method("POST", body) .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); if (response.code() != 200) { return null; } ResponseBody responseBody = response.body(); if (responseBody == null) { return null; } String result = responseBody.string(); return gson.fromJson(result, QueryInfoResponse.class); } } public class QueryInfoRequest { @SerializedName("access_token") private String accessToken; @SerializedName("ma_app_id") private String appId; @SerializedName("url_link") private String urlLink; public QueryInfoRequest(String accessToken, String appId, String urlLink) { this.accessToken = accessToken; this.appId = appId; this.urlLink = urlLink; } public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public String getAppId() { return appId; } public void setAppId(String appId) { this.appId = appId; } public String getUrlLink() { return urlLink; } public void setUrlLink(String urlLink) { this.urlLink = urlLink; } } public class QueryInfoResponse { @SerializedName("err_no") private long errNo; @SerializedName("err_tips") private String errTips; @SerializedName("url_link_info") private UrlLinkInfo linkInfo; public QueryInfoResponse(long errNo, String errTips, UrlLinkInfo linkInfo) { this.errNo = errNo; this.errTips = errTips; this.linkInfo = linkInfo; } public long getErrNo() { return errNo; } public void setErrNo(long errNo) { this.errNo = errNo; } public String getErrTips() { return errTips; } public void setErrTips(String errTips) { this.errTips = errTips; } public UrlLinkInfo getLinkInfo() { return linkInfo; } public void setLinkInfo(UrlLinkInfo linkInfo) { this.linkInfo = linkInfo; } } public class UrlLinkInfo { @SerializedName("app_name") private String appName; @SerializedName("ma_app_id") private String appId; @SerializedName("path") private String path; @SerializedName("query") private String query; @SerializedName("create_time") private long createTime; @SerializedName("expire_time") private long expireTime; public UrlLinkInfo(String appName, String appId, String path, String query, long createTime, long expireTime) { this.appName = appName; this.appId = appId; this.path = path; this.query = query; this.createTime = createTime; this.expireTime = expireTime; } public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } public String getAppId() { return appId; } public void setAppId(String appId) { this.appId = appId; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getQuery() { return query; } public void setQuery(String query) { this.query = query; } public long getCreateTime() { return createTime; } public void setCreateTime(long createTime) { this.createTime = createTime; } public long getExpireTime() { return expireTime; } public void setExpireTime(long expireTime) { this.expireTime = expireTime; } }
JavaScript
const axios = require('axios'); module.exports = function getQueryInfo(accessToken, appId, urlLink) { var config = { method: 'post', url: 'https://developer.toutiao.com/api/apps/url_link/query_info', headers: { 'Content-Type': 'application/json', "Accept-Encoding": "*" }, data : { access_token: accessToken, url_link: urlLink, ma_app_id: appId } }; return axios(config) .then(function (response) { if(response.data && response.data.err_no === 0){ return response.data.url_link_info; } throw new Error('查询urlink信息失败:'+ response.data && response.data.err_tips) }); }
查询生成链接额度
查询单天生成小程序链接所剩额度。
Go
type QuotaInfo struct { URLLinkUsed int `json:"url_link_used"` URLLinkLimit int `json:"url_link_limit"` } type LinkQueryQuotaReq struct { AccessToken string `json:"access_token" mask:"session"` MaAppId string `json:"ma_app_id"` } type LinkQueryQuotaResp struct { ErrorCode int64 `json:"err_no"` ErrorTips string `json:"err_tips"` URLLinkQuota QuotaInfo `json:"url_link_quota"` } func QueryQuota(token string, appid string) { url := "https://developer.toutiao.com/api/apps/url_link/query_quota" method := "POST" reqStruct := &LinkQueryQuotaReq{ AccessToken: token, MaAppId: appid, } reqBody, _ := json.Marshal(reqStruct) payload := strings.NewReader(string(reqBody)) client := &http.Client{} req, err := http.NewRequest(method, url, payload) if err != nil { fmt.Println(err) return } req.Header.Add("Content-Type", "application/json") res, err := client.Do(req) if err != nil { fmt.Println(err) return } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println(err) return } fmt.Println(string(body)) }
Java
// java import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import okhttp3.*; public class QueryQuota { public static QueryQuotaResponse QueryQuota(QueryQuotaRequest queryQuotaRequest) throws Exception { OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create(); String queryQuotaRequestString = gson.toJson(queryQuotaRequest); RequestBody body = RequestBody.create(mediaType, queryQuotaRequestString); Request request = new Request.Builder() .url("https://developer.toutiao.com/api/apps/url_link/query_quota") .method("POST", body) .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); if (response.code() != 200) { return null; } ResponseBody responseBody = response.body(); if (responseBody == null) { return null; } String result = responseBody.string(); return gson.fromJson(result, QueryQuotaResponse.class); } } public class QueryQuotaRequest { @SerializedName("access_token") private String accessToken; @SerializedName("ma_app_id") private String appId; public QueryQuotaRequest(String accessToken, String appId) { this.accessToken = accessToken; this.appId = appId; } public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public String getAppId() { return appId; } public void setAppId(String appId) { this.appId = appId; } } public class QueryQuotaResponse { @SerializedName("err_no") private long errNo; @SerializedName("err_tips") private String errTips; @SerializedName("url_link_quota") private QuotaInfo quotaInfo; public QueryQuotaResponse(long errNo, String errTips, QuotaInfo quotaInfo) { this.errNo = errNo; this.errTips = errTips; this.quotaInfo = quotaInfo; } public long getErrNo() { return errNo; } public void setErrNo(long errNo) { this.errNo = errNo; } public String getErrTips() { return errTips; } public void setErrTips(String errTips) { this.errTips = errTips; } public QuotaInfo getQuotaInfo() { return quotaInfo; } public void setQuotaInfo(QuotaInfo quotaInfo) { this.quotaInfo = quotaInfo; } } public class QuotaInfo { @SerializedName("url_link_used") private int urlLinkUsed; @SerializedName("url_link_limit") private int urlLinkLimit; public QuotaInfo(int urlLinkUsed, int urlLinkLimit) { this.urlLinkUsed = urlLinkUsed; this.urlLinkLimit = urlLinkLimit; } public int getUrlLinkUsed() { return urlLinkUsed; } public void setUrlLinkUsed(int urlLinkUsed) { this.urlLinkUsed = urlLinkUsed; } public int getUrlLinkLimit() { return urlLinkLimit; } public void setUrlLinkLimit(int urlLinkLimit) { this.urlLinkLimit = urlLinkLimit; } }
JavaScript
const axios = require("axios"); module.exports=function queryQuota(accessToken,appId,) { var config = { method: 'post', url: 'https://developer.toutiao.com/api/apps/url_link/query_quota', headers: { 'Content-Type': 'application/json' }, data : { access_token: accessToken, ma_app_id: appId } }; return axios(config) .then(function (response) { if(response.data && response.data.err_no === 0){ return response.data.url_link_quota; } throw new Error('查询urlink限额失败:' + response.data && response.data.err_tips) }) }
整体流程参考
Go
// go var appid = "" var secret = "" func main() { token := accesstoken.Get(appid, secret) if token != "" { // 根据业务需求填入相关参数 // 生成二维码 qrcode.CreateQrcode(token, "", "", 0, nil, nil, false) // 生成分享链接 url := urllink.Generate(token, "", appid, "", "{}", 0) // 查询链接相关基本信息 urllink.QueryInfo(token, url, "") // 查询请求链接剩余额度 urllink.QueryQuota(token, appid) } }
Java
// java public class main { static String AppId = ""; static String Secret = ""; public static void main(String[] args) throws Exception { String token = AccessToken.Get(AppId, Secret); // 用户自行自定义参数 // 生成分享二维码图片 QrCodeRequest qrCodeRequest = new QrCodeRequest(token, "", "", 0, null, null, false); byte[] imgByte = QrCode.Create(qrCodeRequest); // 生成分享链接 GenerateRequest generateRequest = new GenerateRequest(token, "", AppId, "", "{}", 0); GenerateResponse generateResponse = Generate.Generate(generateRequest); // 查询链接基本信息 assert generateResponse != null; QueryInfoRequest queryInfoRequest = new QueryInfoRequest(token, AppId, generateResponse.getUrlLink()); QueryInfoResponse queryInfoResponse = QueryInfo.QueryInfo(queryInfoRequest); // 查询生成链接额度 QueryQuotaRequest queryQuotaRequest = new QueryQuotaRequest(token, AppId); QueryQuotaResponse queryQuotaResponse = QueryQuota.QueryQuota(queryQuotaRequest); } }
JavaScript
const fs = require('fs'); const path =require('path'); const getAccessToken = require('./access-token'); const createQrCode = require('./create-qrcode'); const createUrlLink = require('./create-url-link'); const queryLinkInfo = require('./query-link-info'); const queryLinkQuota = require('./query-link-quota'); const appId = ''; // 填写小程序id const secret = ''; // 填写对应小程序后台密钥 async function getShareData() { try { const accessToken = await getAccessToken(appId, secret); const qrImgData = await createQrCode(accessToken, { path: "pages/index", line_color: { "r": 0, "g": 0, "b": 0 }, background: { "r": 255, "g": 255, "b": 255 } }); fs.writeFileSync(path.join(__dirname,'qrcode-demo.png'), qrImgData); const urlLink = await createUrlLink(accessToken, appId, { query: '{}', path: 'pages/index', expireTime: Math.floor(Date.now() / 1000) + 60 * 24 * 180 }); console.log("urlLink:", urlLink); const urlLinkInfo = await queryLinkInfo(accessToken, appId, urlLink); console.log("urlLinkInfo:", urlLinkInfo); const urlLinkQuota = await queryLinkQuota(accessToken, appId); console.log("urlLinkQuota:", urlLinkQuota); } catch (error) { console.log(error); } }
基本文档-含调用示例
分享二维码
根据传入参数,生成分享使用的二维码图片:createQRCode
生成分享链接
根据开发者传入参数,生成可访问的小程序分享链接:Generate
查询分享链接信息
根据链接查询相关生成信息:QueryInfo
查询分享链接额度
根据链接查询当前小程序配额:QueryQuota
总结
恭喜,你已经完成了小程序分享 Codelab。
你在该 Codelab 中了解了:
- •如何创建分享模板
- •如何配置分享页面
- •如果获取分享链接
接下来,你可以将小程序:
- •通过抖音私信分享
- •通过微信好友或朋友圈分享
- •通过链接分享