Skip to content

预警 API

单点查询 API

TIP

目前支持中国、日本的气象预警信息,其他国家和地区的预警信息正在逐步增加中。

每次调用消耗接口调用额度一次。

bash
curl "https://singer.caiyunhub.com/v3/alert/location?token=token&longitude=113.31685980902778&latitude=23.1251321072048"

请求参数:

FieldTypeDescription
longitudefloat经度
latitudefloat纬度

返回结构

json
{
  "alerts": [
    {
      "alert_type": 156110203, // 预警类型,参考 AlertType
      "area_code": "110102", // 区域编码
      "color": {
        "blue": 255,
        "green": 100,
        "red": 55
      },
      "data": [
        {
          "language_code": "zh-CN", // 语言编码
          "name": "暴雨蓝色预警", // 预警名称
          "text": "西城区气象台29日15时30分发布暴雨蓝色预警,预计29日夜间至30日夜间,西城区将出现小时降雨量超过30毫米的强降水,低洼地区可能出现积水,请注意防范。(数据来源:国家预警信息发布中心)", // 预警内容
          "title": "西城区气象台发布暴雨蓝色预警[IV/一般]" // 预警标题
        }
      ],
      "id": "ALERT_CN_11010241600000_20240729153126", // 业务分配的唯一标识
      "publish_time": 1722238200, // 预警发布时间戳(秒)
      "region_code": "CN", // ISO 3166-1 Alpha-2 code
      "source": 1 // 预警来源机构,参考 AlertSource
    }
  ]
}

Alerts

FieldTypeDescription
alertsAlertRecord预警记录

AlertRecord

FieldTypeDescription
alert_typeAlertType预警类型
area_codestring区域编码,可能是行政区划编码,也可能相关机构分配的区域编码
colorRGB Object颜色,根据各国气象局的标准定义的颜色;RGBA 中如果值为 0 则不返回
dataAlertData预警信息
idstring业务分配的唯一标识,不要直接解析 id 作为业务逻辑
publish_timeint64预警发布时间戳(秒)
region_codestringISO 3166-1 Alpha-2 code
sourceAlertSource预警来源机构
statusint32预警状态:1 表示预警发布,2 表示预警继续,3 表示预警取消,4 表示预警过期;其中 3&4 只在预警 Webhook 推送中提供

AlertData

FieldTypeDescription
language_codestring语言编码
levelstring预警级别, 本地化的描述
namestring预警名称
textstring预警内容
titlestring预警标题

AlertSource

随时可能新增枚举值,代码请做好兼容处理。

NumberDescription
1中国气象局
2日本气象厅

AlertType

随时可能新增枚举值,代码请做好兼容处理。

枚举值以 ISO 3166-1 numeric-3 code 开头,后面跟随具体的预警类型。 比如如下表格里,中国的前缀为 156,日本的前缀为 392

NumberDescription
156100000突发事件
156110000自然灾害
156110100水旱灾害
156110101洪水
156110108枯水
156110109中小河流洪水和山洪气象风险
156110151山洪灾害事件
156110152农业干旱
156110154生态干旱
156110200气象灾害
156110201台风事件
156110202龙卷风事件
156110203暴雨事件
156110204暴雪事件
156110205寒潮事件
156110206大风事件
156110207沙尘暴事件
156110208低温冻害事件
156110209高温事件
156110210热浪事件
156110211干热风
156110212下击暴流事件
156110213雪崩事件
156110214雷电事件
156110215冰雹事件
156110216霜冻事件
156110217大雾事件
156110218低空风切变事件
156110219
156110220雷雨大风
156110221道路结冰
156110222干旱
156110223海上大风
156110224高温中暑
156110225森林火险
156110226草原火险
156110227冰冻
156110229重污染
156110230低温雨雪冰冻
156110231强对流
156110232臭氧
156110233大雪
156110234寒冷
156110235连阴雨
156110236渍涝风险
156110237地质灾害
156110238强降雨
156110239强降温
156110240雪灾
156110241森林(草原)火险
156110243雷暴
156110247春季沙尘天气趋势预警
156110248降温
156110249台风暴雨
156110250严寒
156110251沙尘
156110252海上雷雨大风预警信号
156110254海上雷电预警信号
156110255海上台风预警信号
156110256低温
156110257道路冰雪
156110258雷暴大风
156110262海区大风
156110265海区大雾
156110286低温凝冻
156110287低温冷害
156110291低温冰冻
39200010大雨
39200020大雪
39200030風雪
39200040
39200050強風
39200060波浪
39200070融雪
39200080洪水
39200090高潮
39200100濃霧
39200110乾燥
39200120なだれ(雪崩)
39200130低温
39200140
39200150着氷
39200160着雪
39200170暴風雪
39200180暴風

预警颜色说明

《GB/T 37230—2018》定义了中国预警颜色规范,其中颜色等级对照如下:

等级颜色RGB 值
广东特有预警级别白色255/255/255
IV 级(一般)蓝色55/100/255
III 级(较重)黄色250/230/0
II 级(严重)橙色240/150/20
I 级(特别严重)红色220/40/40

批量获取 API

目前支持中国的气象预警信息,其他国家和地区的预警信息正在逐步增加中。

每次调用消耗接口调用额度一次。

本部分 API 属于增值服务,开发者 Token 需要额外开通权限,请联系商务

本接口重点为需要在地图叠加全国预警分布的客户提供一个方便的批量获取 API。 直接返回 GeoJSON 格式的数据,方便直接和地图交互。

调用方式:

bash
curl "https://singer.caiyunhub.com/v3/alert/all?token=token&region_code=CN" \
     -H 'If-None-Match: 123hfjkds678' \
     -H 'Accept-Encoding: gzip, zlib, deflate, zstd, br'

正常情况下,接口在 Response Header 中会含有一个 x-cy-etag 值,在下一次调用时将 Etag 值赋给请求 Header 中的 If-None-Match, 如果返回 HTTP 304 则表示数据没有变化,可以直接使用上一次的数据。

返回结构

json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": { "type": "Point", "coordinates": [118.702032, 41.018482] },
      "id": "ALERT_CN_13088141600000_20240806111120",
      "properties": {
        "alert_type": 156110214,
        "area_code": "130881",
        "color": { "red": 250, "green": 230 },
        "data": [
          {
            "language_code": "zh-CN",
            "title": "平泉市气象台发布雷电黄色预警[Ⅲ级/较重]",
            "text": "平泉市气象台2024年08月06日11时10分发布雷电黄色预警信号:预计未来6小时内,我市全部乡镇将受雷电天气影响,雷雨时可能伴有雷暴大风、短时强降水和冰雹等强对流天气,请注意防范。(数据来源:国家预警信息发布中心)",
            "name": "雷电黄色预警"
          }
        ],
        "id": "ALERT_CN_13088141600000_20240806111120",
        "publish_time": 1722913880,
        "region_code": "CN",
        "source": 1,
        "status": 1
      }
    },
    {
      "type": "Feature",
      "geometry": { "type": "Point", "coordinates": [125.744654, 42.284594] },
      "id": "ALERT_CN_22052441600000_20240806103348",
      "properties": {
        "alert_type": 156110214,
        "area_code": "220524",
        "color": { "red": 250, "green": 230 },
        "data": [
          {
            "language_code": "zh-CN",
            "title": "柳河县气象台 发布雷电黄色预警[III级/较重]",
            "text": "预计未来6小时内,我县有分布不均的雷电天气,可能会造成雷电灾害,局部地方伴有短时强降水、雷暴大风或冰雹等强对流天气,县应急局与县气象局联合提醒相关部门和广大群众注意加强防范(数据来源:国家预警信息发布中心)",
            "name": "雷电黄色预警"
          }
        ],
        "id": "ALERT_CN_22052441600000_20240806103348",
        "publish_time": 1722911788,
        "region_code": "CN",
        "source": 1,
        "status": 1
      }
    }
  ]
}

Webhook 推送

访问限制

本部分 API 属于增值服务,开发者 Token 需要额外开通权限,请联系商务

预警信息支持通过 Webhook 推送,单条预警记录的结构与 API 返回结构一致。

POST Body:

json
{
  "sign": "xxxx", // 根据规则生成的签名
  "nonce": "xxxx", // 随机字符串
  "server_time": 1722238200,
  "alert": {
    "alert_type": 156110203,
    "area_code": "110102",
    "color": {
      "blue": 255,
      "green": 100,
      "red": 55
    },
    "data": [
      {
        "language_code": "zh-CN",
        "name": "暴雨蓝色预警",
        "text": "西城区气象台29日15时30分发布暴雨蓝色预警,预计29日夜间至30日夜间,西城区将出现小时降雨量超过30毫米的强降水,低洼地区可能出现积水,请注意防范。(数据来源:国家预警信息发布中心)",
        "title": "西城区气象台发布暴雨蓝色预警[IV/一般]"
      }
    ],
    "id": "ALERT_CN_11010241600000_20240729153126",
    "publish_time": 1722238200,
    "expire_time": 1722238200, // 预警过期时间戳(秒)
    "region_code": "CN",
    "source": 1
  }
}

签名计算规则

计算规则为:

sign = md5("{token}-{id}-{publish_time}-{nonce}-{server_time}")

Python/Go/Java/PHP 示例代码如下:

py
import hashlib


def generate_sign(token, id, publish_time, nonce, server_time):
    # 拼接字符串
    data = f"{token}-{id}-{publish_time}-{nonce}-{server_time}"
    # 计算 MD5 签名
    sign = hashlib.md5(data.encode()).hexdigest()
    return sign


# 示例数据
token = "your_token"
id = "your_id"
publish_time = 1234567890
nonce = "your_nonce"
server_time = 9876543210

# 生成签名
sign = generate_sign(token, id, publish_time, nonce, server_time)
print(sign)
# Output: ed72493981fff6ddc4770dc70aeeb1ad
go
package main

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
)

func generateSign(token, id string, publishTime int64, nonce string, serverTime int64) string {
	// 拼接字符串
	data := fmt.Sprintf("%s-%s-%d-%s-%d", token, id, publishTime, nonce, serverTime)
	// 计算 MD5 签名
	hash := md5.Sum([]byte(data))
	return hex.EncodeToString(hash[:])
}

func main() {
	// 示例数据
	token := "your_token"
	id := "your_id"
	publishTime := int64(1234567890)
	nonce := "your_nonce"
	serverTime := int64(9876543210)

	// 生成签名
	sign := generateSign(token, id, publishTime, nonce, serverTime)
	fmt.Println(sign)
    // Output: ed72493981fff6ddc4770dc70aeeb1ad
}
java
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SignDemo {

    public static void main(String[] args) {
        String token = "your_token";
        String id = "your_id";
        long publishTime = 1234567890L;
        String nonce = "your_nonce";
        long serverTime = 9876543210L;

        // 拼接字符串
        String input = String.format("%s-%s-%d-%s-%d", token, id, publishTime, nonce, serverTime);

        // 计算 MD5 签名
        String sign = md5(input);

        // 输出签名
        System.out.println("计算出的签名: " + sign);

        // 验证是否与预期结果匹配
        String expectedSign = "ed72493981fff6ddc4770dc70aeeb1ad";
        if (sign.equals(expectedSign)) {
            System.out.println("签名匹配!");
        } else {
            System.out.println("签名不匹配!");
        }
    }

    // 计算 MD5 哈希
    public static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : hashBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}
php
<?php

function calculateSign($token, $id, $publishTime, $nonce, $serverTime) {
    // 拼接字符串
    $input = sprintf("%s-%s-%d-%s-%d", $token, $id, $publishTime, $nonce, $serverTime);

    // 计算 MD5 签名
    return md5($input);
}

// 样例数据
$token = "your_token";
$id = "your_id";
$publishTime = 1234567890;
$nonce = "your_nonce";
$serverTime = 9876543210;

// 计算签名
$sign = calculateSign($token, $id, $publishTime, $nonce, $serverTime);

echo "计算出的签名: " . $sign . "\n";

// 预期的签名
$expectedSign = "ed72493981fff6ddc4770dc70aeeb1ad";

// 验证签名是否匹配
if ($sign === $expectedSign) {
    echo "签名匹配!\n";
} else {
    echo "签名不匹配!\n";
}
?>
更多语言签名计算代码

上述代码都是用 LLM 生成的,使用的 prompts 如下:

md
我有一个签名的计算方式为:

sign = md5("{token}-{id}-{publish_time}-{nonce}-{server_time}")

其中:

- token: str, eg "your_token"
- id: str, eg "your_id"
- publish_time: int64, eg 1234567890
- nonce: str, eg "your_nonce"
- server_time: int64, eg 9876543210

帮我编写对应的 Python&Go 的 demo,并用样例数据验证签名计算是否为 `ed72493981fff6ddc4770dc70aeeb1ad`

请根据自己的需求修改 prompts,并用样例数据验证签名计算是否正确。