npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ape-js-sdk

v1.1.4

Published

APE JS SDk

Downloads

4

Readme

腾讯云APE-SDK接入文档

概述:

​ 此文档适用于腾讯云正版图库直通车的合作客户,将SDK接入自己的平台后,客户可以更方便的使用腾讯云正版图库提供的各种能力。

接入前提:

​ 您已注册腾讯云账号,完成实名认证,并成为腾讯云图库会员

文档目录:

一、引入sdk并初始化实例

二、后端鉴权生成签名

三、查询频道对应的图片分类

四、搜索图片

五、获取图片Url

六.各编程语言语言签名示例

一、引入SDK并初始化实例

通过npm安装ape-js-sdk

npm i ape-js-sdk

在您的web页面引入sdk,并实例化对象,代码示例如下:

import ApeSdk from 'ape-js-sdk'

const sdk = new ApeSdk({
	sign: 'XXXXX’
})

参数说明:

| 字段名 | 类型 | 是否必填 | 描述 | | ------ | ------ | -------- | -------------------------- | | sign | string | 是 | 用户签名,由开发者后端提供 |

二、后端鉴权生成签名

签名授权交互如下:

授权流程:

  1. 开发者浏览器端向开发者服务端发起请求,申请浏览器端访问签名;

  2. 开发者服务端在对请求来源及内容做适当鉴权之后,根据签名算法,生成对应操作的访问签名,并返回给浏览器端;

  3. 开发者浏览器端将访问签名传递给图库直通车 APE-SDK;

  4. 图库直通车APE-SDK 会携带签名执行相关操作,图库直通车服务端在进行签名合法性校验,以及用户操作权限校验之后,会执行相应操作。

签名生成步骤:

  1. 获取云API密钥:

    • 登录腾讯云控制台,选择 云产品 > 访问管理 > API密钥管理;

    • 获取云API密钥,如果没有可以新建,获取一对SecretId和SecretKey备用。

  2. 拼接明文串:

​ 按照 URL QueryString 的格式要求拼接签名明文串 original,其格式如下:

secretId=[secretId]&currentTimeStamp=[currentTimeStamp]&expireTime=[expireTime]&random=[random]&channelId=[channelId]&imageDownloadMaxNum=[imageDownloadMaxNum]
  • 上述 original 中的[secretId][currentTimeStamp][expireTime][random][channelId][imageDownloadMaxNum]需要自行替换成具体的参数值。
  • original 除了可以包含必选参数,还可包含任意多个选填参数,详细请参见 签名参数
  • 参数值必须经过 UrlEncode,否则可能导致 QueryString 解析失败。
  1. 将明文串转为最终签名。

下面以 Java 语言作为示例进行实现,其他语言的实现请参见 签名示例

  1. 用已获取的 SecretKey 对明文串 original 进行 HMAC-SHA1 加密,得到 signatureTmp:
SecretKeySpec secretKey = new SecretKeySpec(this.secretKey.getBytes("UTF-8"), mac.getAlgorithm());
mac.init(secretKey);
byte[] signatureTmp = mac.doFinal(original.getBytes("UTF-8"));
  1. 将明文串 original 使用 UTF-8 编码成字节数组,然后把 signatureTmp 与该数组进行合并,最后把合并后的结果进行 Base64 编码,得到最终签名 signature:
String signature = base64Encode(byteMerger(signatureTmp, original.getBytes("utf8")));

签名参数说明:

| 参数名称 | 必选 | 类型 | 说明 | | ------------------- | :--: | ------- | :----------------------------------------------------------: | | secretId | 是 | String | 云 API 密钥 中的 SecretId。 | | currentTimeStamp | 是 | Integer | 当前 Unix 时间戳。 | | expireTime | 是 | Integer | 签名到期 Unix 时间戳,当currentTimeStamp>expireTime时,签名会失效。expireTime = currentTimeStamp + 签名有效时长。 | | random | 是 | Integer | 随机数,类型为32位无符号整型。 | | channelId | 是 | String | 频道ID, | | imageDownloadMaxNum | 是 | Integer | 图片下载最大数量,当同一签名下载图片次数超过此限制,签名将失效。 |

三.查询频道详细信息

此方法用于获取频道的详细信息,包括图片分类名称等,代码示例如下:

sdk.DescribeChannel().then((res)=>{

});

参数说明:

| 类别 | 字段名 | 类型 | 是否必填 | 描述 | | -------- | ------------- | --------------- | -------- | -------- | | response | CategoryNames | Array of String | | 分类名称 | | | ChannelName | String | | 频道名称 |

四.搜索图片

此方法用于根据各种条件搜索图片结果,代码示例如下:

sdk.SearchImage({
    Keyword: 'XXX',
    Orientation: Orientation.ALL,
    ImageSenseType: SenseType.ALL,
    Category: '',
    Offset: 0,
    Limit: 20,
}).then((res)=>{

});

参数说明:

| 类别 | 字段名 | 类型 | 是否必填 | 描述 | | -------- | :------------- | :----------------: | :------: | :----------------------------------------------------------: | | request | Offset | Number | 否 | 页码,默认0 | | | Limit | Number | 否 | 页长,默认100 | | | Keyword | String | 否 | 关键词,可以为空字符串 | | | Orientation | String | 否 | 构图方式: Orientation.ALL (全部)Orientation.HORIZONTAL (横图)Orientation.VERTICAL (竖图)Orientation.SQUARE (方图) | | | ImageSenseType | String | 否 | 图片类型: SenseType.ALL (全部)SenseType.PHOTO (照片)SenseType.ILLUSTRATION (插画)SenseType.TEMPLATE (模板) | | | Category | String | 否 | 分类名称 ,例如:建筑、背景、季节等 | | response | Total | Number | | 搜索结果总数 | | | Items | Array of ImageItem | | 图片素材列表 |

ImageItem

| 字段名 | 类型 | 描述 | | :--------- | :----: | :--------: | | ImageId | String | 图片Id | | Title | String | 图片标题 | | PreviewUrl | String | 预览图链接 | | Height | Number | 图高 | | Width | Number | 图宽 |

五.引用素材(获取图片原图链接)

此方法用于获取图片源地址,代码示例如下:

sdk.DownloadImage({
   ImageId: 'ape-xkdiq1',
}).then((res)=>{

});

参数说明:

| 类别 | 字段名 | 类型 | 是否必填 | 描述 | | -------- | -------- | ------ | -------- | ------- | | request | ImageId | String | 是 | 图片Id | | response | ImageUrl | String | | 源图url |

注意:源图url 有效期 30 分钟,请勿直接将该 URL 持久存储,如有必要请将图片内容转存到自己的图片存储服务。

六.各编程语言生成签名示例

  • Java 签名示例
import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class ApeSign {
    public static void main(String[] args) throws Exception {
        Long currentTime = System.currentTimeMillis() / 1000;
        Integer random = new Random().nextInt(java.lang.Integer.MAX_VALUE);
        Long expireTime = currentTime + 5 * 60; // 5分钟有效
        Integer imageDownloadMaxNum = 20; // 签名可下载图片最大次数

        HashMap<String, String> paramMap = new HashMap<String, String>();
        // 必填参数
        paramMap.put("secretId", "Your SecretId");
        paramMap.put("currentTimeStamp", currentTime.toString());
        paramMap.put("random", random.toString());
        paramMap.put("expireTime", expireTime.toString());
        paramMap.put("channelId", "Your channelId");
        paramMap.put("imageDownloadMaxNum", imageDownloadMaxNum);
        

        String secretKey = "Your SecretKey";
        String original = urlEncodeUTF8(paramMap);

        Mac mac = Mac.getInstance("HmacSHA1");
        SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), mac.getAlgorithm());
        mac.init(keySpec);
        byte[] hash = mac.doFinal(original.getBytes("UTF-8"));
        byte[] signBuffer = byteMerger(hash, original.getBytes("UTF-8"));
        String sign = new String(new BASE64Encoder().encode(signBuffer).getBytes());
        sign = sign.replace(" ", "").replace("\n", "").replace("\r", "");

        System.out.println(sign);
    }

    private static byte[] byteMerger(byte[] byte1, byte[] byte2) {
        byte[] byte3 = new byte[byte1.length + byte2.length];
        System.arraycopy(byte1, 0, byte3, 0, byte1.length);
        System.arraycopy(byte2, 0, byte3, byte1.length, byte2.length);
        return byte3;
    }

    private static String urlEncodeUTF8(Map<String, String> map) throws Exception {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(String.format("%s=%s",
                    URLEncoder.encode(entry.getKey(), "UTF-8"),
                    URLEncoder.encode(entry.getValue(), "UTF-8")
            ));
        }
        return sb.toString();
    }
}
  • Go 签名示例
package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"math/rand"
	"net/url"
	"strconv"
	"time"
)

func main() {
	secretId := "Your SecretId"
	secretKey := "Your SecretKey"
    imageDownloadMaxNum := 20 // 签名可下载图片最大次数

	currentTime := time.Now().Unix()
	expireTime := currentTime + 5 * 60 // 签名有效期:5分钟
	rand.Seed(time.Now().Unix())
	random := rand.Uint32()

	values := url.Values{}
	values.Add("secretId", secretId)
	values.Add("currentTimeStamp", strconv.FormatInt(currentTime, 10))
	values.Add("expireTime", strconv.FormatInt(expireTime, 10))
	values.Add("random", strconv.Itoa(int(random)))
    values.Add("channelId", "Your channelId");
	values.Add("imageDownloadMaxNum", imageDownloadMaxNum);

	queryStr := values.Encode()
	mac := hmac.New(sha1.New, []byte(secretKey))
	mac.Write([]byte(queryStr))
	macBuffer := mac.Sum(nil)

	origin := string(macBuffer) + queryStr
	signature := base64.StdEncoding.EncodeToString([]byte(origin))
	fmt.Println(signature)
}
  • Python 签名示例
#!/usr/local/bin/python3
#coding=utf-8

import time
import random
import hmac
import hashlib
import base64
from urllib.parse import urlencode

# 确定签名的当前时间和失效时间
currentTime = int(time.time())
expireTime = currentTime + 5 * 60  # 签名有效期:5分钟
imageDownloadMaxNum = 20 # 签名可下载图片最大次数

# 参数
argList = {
    "secretId" : "Your SecretId",
    "currentTimeStamp" : currentTime,
    "expireTime" : expireTime,
    "random" : random.randint(0, 999999),
    "channelId": "Your channelId",
    "imageDownloadMaxNum": imageDownloadMaxNum
}

secretKey = "Your SecretKey"

# 计算签名
original = urlencode(argList)
secretKeyHmac = hmac.new(bytes(secretKey, 'utf-8'), bytes(original, 'utf-8'), hashlib.sha1)
secretKeySha = secretKeyHmac.digest()
signTemp = bytes(secretKeySha) + bytes(original, 'utf-8')
sign = base64.b64encode(signTemp)

print("sign: ", sign)
  • PHP 签名示例
<?php
// 确定签名的当前时间和失效时间
$currentTime = time();
$expireTime = $currentTime + 5 * 60;  // 签名有效期:5分钟
$imageDownloadMaxNum = 20; // 签名可下载图片最大次数

// 必填参数
$arg_list = array(
    "secretId" => "Your SecretId",
    "currentTimeStamp" => $currentTime,
    "expireTime" => $expireTime,
    "random" => rand(),
    "channelId" => "Your channelId",
    "imageDownloadMaxNum" => imageDownloadMaxNum,
);

$secretKey = "Your SecretKey";

// 计算签名
$original = http_build_query($arg_list);
$signature = base64_encode(hash_hmac('SHA1', $original, $secretKey, true).$original);

echo $signature;
  • Node.js 签名示例
var querystring = require("querystring");
var crypto = require('crypto');

// 确定签名的当前时间和失效时间
var currentTime = parseInt((new Date()).getTime() / 1000);
var expireTime = currentTime + 5 * 60;  // 签名有效期:5分钟
var imageDownloadMaxNum = 20; // 签名可下载图片最大次数

// 必填参数
var arg_list = {
    secretId : "Your SecretId",
    currentTimeStamp : currentTime,
    expireTime : expireTime,
    random : Math.round(Math.random() * Math.pow(2, 32)),
    channelId: "Your channelId", 
    imageDownloadMaxNum: imageDownloadMaxNum,
};

var secretKey = "Your SecretKey";

// 计算签名
var orignal = querystring.stringify(arg_list);
var orignal_buffer = Buffer.from(orignal, "utf8");
var hmac = crypto.createHmac("sha1", secretKey);
var hmac_buffer = hmac.update(orignal_buffer).digest();
var sign = Buffer.concat([hmac_buffer, orignal_buffer]).toString("base64");

console.log(sign);