第一个demo

小组件采用 javascript 编写, 下面以带天气预报的闹钟为例, 来看一下我们的小组件长什么样子。

文件说明

一个小组件通常由 封面图(icon.png)、配置文件(widget.json)、主要代码(widget.js)、测试代码(test.js)组成

配置文件

小组件配置文件为 json 格式

// widget.json
{
    "id": "widget.agcplayer.alarm-clock", // 小组件唯一ID
    "name": "Alarm Clock", // 小组件名称
    "type": "alarm-clock", // 小组件类型
    "author": "Sam", // 开发作者
    "version": "0.0.1", // 版本号
    "agcplayer-require": "^0.0.1", // AGC Player 最低要求版本
    "platform": "all", // 支持平台 all | ios | ipadOS | macOS | Android | Linux | Win
    "summary": "This is a Alarm Clock widget.", // 简短介绍
    "description": "This is a Alarm Clock widget, JavaScript script.", // 详细介绍
    "disclaimer": "For demonstration only." // 免责声明
}

主要代码

// widget.js
const ua =
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36";

// 10分钟请求一次天气接口
const expireTime = 10 * 60 * 1000
// 缓存数据
const caches = {
  data: {}
}

// 获取天气数据
async function getWeather() {
  const response = await fetch(`https://assets.msn.com/service/segments/recoitems/weather?apikey=0QfOX3Vn51YCzitbLaRkTTBadtWpgTN8NZLW0C1SEM&activityId=11E1D056-1F06-447C-957D-7A61FC223B52&ocid=windows-windowshp-feeds&cm=zh-cn&it=web&user=m-213FFBD1D3716BC02EF9EF19D22B6A68&scn=ANON&appId=4de6fc9f-3262-47bf-9c99-e189a8234fa2&wrapodata=false&includemapsmetadata=true&cuthour=true&filterRule=card&distanceinkm=0&regionDataCount=20&orderby=distance&days=5&pageOcid=windows-windowshp-peregrine&source=undefined_csr&hours=13&fdhead=prg-1sw-wxinst%2Cprg-1sw-wxevolnoti&contentcount=3&region=xl&market=zh-xl&locale=zh-cn`, {
    headers: {
      "user-agent": ua,
    },
  })
  const res = await response.json();

  if (res.length && res[0].data) {
    const json = JSON.parse(res[0].data)

    const rs = json.responses
    const location = json.userProfile.location
    if (rs.length) {
      const { weather } = rs[0];
      const current = weather?.[0].current
      const today = weather?.[0].forecast?.days?.[0].daily
      const iconMap = weather?.[0].iconMap
      caches.data = {
        location,
        cap: current.cap,
        symbol: current.symbol,
        temp: current?.temp,
        tempHi: today?.tempHi,
        tempLo: today?.tempLo,
        icon: `${iconMap.iconBase}${iconMap.symbolMap[current.symbol]}`,
        // iconMap
      }

      return caches.data
    }
  }
}

// 开始轮询
async function startLoop() {
  try {
    await getWeather();
  } finally {
    setTimeout(() => {
      startLoop()
    }, expireTime)
  }
}

async function onload() {
  // 第一次调用天气接口后就执行定时器逻辑
  // 每10分走走一次天气接口
  await startLoop()
  // 1s 给 AGC Player post 一次数据
  setInterval(async () => {
    postMessage(JSON.stringify({ time: Date.now(), ...caches.data }))
  }, 1000)
}
// 小组件打开时调用方法
module.exports.onload = onload
// 获取数据方法
module.exports.getWeather = getWeather;

测试代码

// test.js
// node test.js
const addon = require('./widget.js')

;(async() => {
  // const ip = await addon.getIp();
  // console.log(ip)
  // const city = await addon.getCity(ip.ip);
  // console.log(city);
  // const weather = await addon.getWeather("东莞");
  // console.log(weather)
   await addon.onload();
  // console.log(weather)
})()

Last updated