# 章鱼广告 SDK-快应用接入文档

## 快速接入

### 安装

在快应用项目根目录下安装广告模块，每次发布快应用前可更新包版本，新版本中广告体验更好、功能更丰富。

```bash
npm install octopus-quickapp-sdk
# or
yarn add octopus-quickapp-sdk
```

### 添加接口权限

`manifest.json`文件中`features`属性中添加权限声明代码。

```json
"features": [
 {"name": "system.sensor"},
 {"name": "system.prompt"},
 {"name": "system.network"},
 {"name": "system.router"},
 {"name": "system.fetch"},
 {"name": "system.request"},
 {"name": "system.device"},
 {"name": "system.package"},
 {"name": "system.storage"},
 {"name": "system.file"},
 {"name": "@system.clipboard"},
 {"name": "@system.downloadtask"}
]
```

## 信息流广告

### 广告`props`及回调

| 属性名             | 类型   | 默认值 | 说明             |
| ------------------ | ------ | ------ | ---------------- |
| app-id             | string | none   | 章鱼平台应用 ID  |
| ad-id              | string | none   | 章鱼平台广告 ID  |
| donwload-panel | boolean | false   | 下载类广告是否显示下载弹层  |
| width | string | none   | 组件图片或视频的宽度  |
| height | string | none   | 组件图片或视频的高度  |
| muted | boolean | false   | 视频是否静音  |
| autoplay | boolean | true   | 视频是否自动播放   |
| @loaded         | string | none   | 广告加载触发事件 |
| @shown          | string | none   | 广告展示触发事件 |
| @closed         | string | none   | 广告关闭触发事件 |
| @clicked        | string | none   | 广告点击触发事件 |
| @failed-to-load | string | none   | 广告加载失败事件 |
| @empty        | string | none   | 广告无填充内容 |

---

### 代码示例
```js

<import name="octopus-ad" src="octopus-quickapp-sdk/components/index.ux"></import>

<template>
  <div class="page">
    <div class="btn-wrapper">
      <div class="btn" @click="loadAd">
        <text>
          加载广告
        </text>
      </div>
    </div>
    <div if="{{isLoaded}}" class="btn-wrapper">
      <div class="btn" @click="showAd">
        <text>
          显示广告
        </text>
      </div>
    </div>
    <octopus-ad 
      id="ad"
      type="native"
      ad-id="{{adId}}"
      app-id="{{appId}}"
      @loaded="onAdLoad" 
      @shown="onAdShown" 
      @clicked="onAdClick" 
      @closed="onAdClose"
      @empty="onAdEmpty"
      @failed-to-load="onAdFailToLoad"
    >
    </octopus-ad>
  </div>
</template>

<script>
  export default {
    private: {
      appId: '20240327115320',
      adId: '9258',
      isLoaded: false,
    },
    loadAd() {
      this.$child('ad').load()
    },
    showAd() {
      this.$child('ad').show()
    },
    getIsEmpty() {
      const isEmpty = this.$child('ad').getIsEmpty();
      console.log('isEmpty', isEmpty)
    },
    getPrice() {
      const price = this.$child('ad').getPrice();
      console.log('price', price);
    },
    onAdLoad() {
      this.isLoaded = true
      console.log('onAdLoaded')
    },
    onAdShown() {
      console.log('onAdShown')
    },
    onAdClick() {
      console.log('onAdClicked')
    },
    onAdClose() {
      console.log('onAdClosed')
    },
    onAdEmpty() {
      console.log('onAdEmpty')
    },
    onAdFailToLoad() {
      console.log('onAdFailToLoad')
    },
  }
</script>

``````

## 插屏广告

### 广告`props`及回调

| 属性名             | 类型   | 默认值 | 说明             |
| ------------------ | ------ | ------ | ---------------- |
| app-id             | string | none   | 章鱼平台应用 ID  |
| ad-id              | string | none   | 章鱼平台广告 ID  |
| donwload-panel | boolean | false   | 下载类广告是否显示下载弹层  |
| width | string | none   | 组件图片或视频的宽度  |
| height | string | none   | 组件图片或视频的高度  |
| muted | boolean | false   | 视频是否静音  |
| autoplay | boolean | true   | 视频是否自动播放   |
| @loaded         | string | none   | 广告加载触发事件 |
| @shown          | string | none   | 广告展示触发事件 |
| @closed         | string | none   | 广告关闭触发事件 |
| @clicked        | string | none   | 广告点击触发事件 |
| @empty        | string | none   | 广告无填充内容 |
| @failed-to-load | string | none   | 广告加载失败事件 |

### 代码示例

```js
<import name="octopus-ad" src="octopus-quickapp-sdk/components/index.ux"></import>

<template>
  <div class="page">
    <div class="btn-wrapper">
      <div class="btn" @click="loadAd">
        <text>
          加载广告
        </text>
      </div>
    </div>
    <div if="{{isLoaded}}" class="btn-wrapper">
      <div class="btn" @click="showAd">
        <text>
          显示广告
        </text>
      </div>
    </div>
    <octopus-ad
      id="ad"
      type="interstitial"
      ad-id="{{adId}}"
      app-id="{{appId}}"
      @loaded="onAdLoad" 
      @shown="onAdShown" 
      @clicked="onAdClick" 
      @closed="onAdClose"
      @empty="onAdEmpty"
      @failed-to-load="onAdFailToLoad"
    >
    </octopus-ad>
  </div>
</template>

<script>
  export default {
    private: {
      appId: '20240327115320',
      adId: '9256',
      isLoaded: false,
    },
    loadAd() {
      this.$child('ad').load()
    },
    showAd() {
      this.$child('ad').show()
    },
    getIsEmpty() {
      const isEmpty = this.$child('ad').getIsEmpty();
      console.log('isEmpty', isEmpty)
    },
    getPrice() {
      const price = this.$child('ad').getPrice();
      console.log('price', price);
    },
    onAdLoad() {
      this.isLoaded = true
      console.log('onAdLoaded')
    },
    onAdShown() {
      console.log('onAdShown')
    },
    onAdClick() {
      console.log('onAdClicked')
    },
    onAdClose() {
      console.log('onAdClosed')
    },
    onAdEmpty() {
      console.log('onAdEmpty')
    },
    onAdFailToLoad() {
      console.log('onAdFailToLoad')
    },
  }
</script>
```

## 开屏广告


### 广告`props`及回调

| 属性名             | 类型   | 默认值 | 说明             |
| ------------------ | ------ | ------ | ---------------- |
| app-id             | string | none   | 章鱼平台应用 ID  |
| ad-id              | string | none   | 章鱼平台广告 ID  |
| donwload-panel | boolean | false   | 下载类广告是否显示下载弹层  |
| width | string | none   | 组件图片或视频的宽度  |
| height | string | none   | 组件图片或视频的高度  |
| muted | boolean | false   | 视频是否静音  |
| autoplay | boolean | true   | 视频是否自动播放   |
| skiptime | string | 5   | 倒计时总时长，2-5秒   |
| @loaded         | string | none   | 广告加载触发事件 |
| @shown          | string | none   | 广告展示触发事件 |
| @closed         | string | none   | 广告关闭触发事件 |
| @clicked        | string | none   | 广告点击触发事件 |
| @empty        | string | none   | 广告无填充内容 |
| @failed-to-load | string | none   | 广告加载失败事件 |
| @tick           | string | none   | 倒计时回调   |


### 代码示例

```js
<import name="octopus-ad" src="octopus-quickapp-sdk/components/index.ux"></import>

<template>
  <div class="page">
    <div class="btn-wrapper">
      <div class="btn" @click="loadAd">
        <text>
          加载广告
        </text>
      </div>
    </div>
    <div if="{{isLoaded}}" class="btn-wrapper">
      <div class="btn" @click="showAd">
        <text>
          显示广告
        </text>
      </div>
    </div>
    <octopus-ad 
      id="ad"
      type="splash"
      skiptime="5"
      ad-id="{{adId}}"
      app-id="{{appId}}"
      entry="pages/Index"
      @loaded="onAdLoad" 
      @shown="onAdShown" 
      @clicked="onAdClick" 
      @closed="onAdClose"
      @empty="onAdEmpty"
      @failed-to-load="onAdFailToLoad" 
      @tick="onTick"
    >
    </octopus-ad>
  </div>
</template>

<script>
  import prompt from '@system.prompt'

  export default {
    private: {
      adId: '9255',
      appId: '20240327115320',
      isLoaded: false,
    },
    loadAd() {
      this.$child('ad').load()
    },
    showAd() {
      this.$child('ad').show()
    },
    getIsEmpty() {
      const isEmpty = this.$child('ad').getIsEmpty();
      console.log('isEmpty', isEmpty)
    },
    getPrice() {
      const price = this.$child('ad').getPrice()
      console.log('price', price)
    },
    onAdLoad() {
      this.isLoaded = true
      console.log('onAdLoaded')
    },
    onAdShown() {
      console.log('onAdShown')
    },
    onTick(e) {
      const { second } = e.detail
      console.log(second)
    },
    onAdClick() {
      console.log('onAdClicked')
    },
    onAdClose() {
      console.log('onAdClosed')
    },
    
    onAdEmpty() {
      console.log('onAdEmpty')
    },
    onAdFailToLoad() {
      console.log('onAdFailToLoad')
    },
  }
</script>
```

## 激励视频广告

### 广告`props`及回调

| 属性名             | 类型   | 默认值 | 说明             |
| ------------------ | ------ | ------ | ---------------- |
| app-id             | string | none   | 章鱼平台应用 ID  |
| ad-id              | string | none   | 章鱼平台广告 ID  |
| donwload-panel | boolean | false   | 下载类广告是否显示下载弹层  |
| width | string | none   | 组件图片或视频的宽度  |
| height | string | none   | 组件图片或视频的高度  |
| muted | boolean | false   | 视频是否静音  |
| autoplay | boolean | true   | 视频是否自动播放   |
| @ad-loaded         | string | none   | 广告加载触发事件 |
| @ad-failed-to-load | string | none   | 广告加载失败事件 |
| @ad-shown          | string | none   | 广告展示触发事件 |
| @ad-clicked        | string | none   | 广告点击触发事件 |
| @ad-closed         | string | none   | 广告关闭触发事件 |
| @ad-clicked        | string | none   | 广告点击触发事件 |
| @ad-video-finished | string | none   | 视频播放完毕回调 |

### 代码示例

```js
<import name="octopus-ad" src="octopus-quickapp-sdk/components/index.ux"></import>

<template>
  <div class="page">
    <div class="btn-wrapper">
      <div class="btn" @click="loadAd">
        <text>
          加载广告
        </text>
      </div>
    </div>
    <div class="btn-wrapper">
      <div class="btn" @click="preloadVideo">
        <text>
          预加载激励视频
        </text>
      </div>
    </div>
    <div if="{{isLoaded}}" class="btn-wrapper">
      <div class="btn" @click="showAd">
        <text>
          显示激励视频
        </text>
      </div>
    </div>
    <octopus-ad 
      id="ad"
      type="rewardVideo"
      ad-id="{{adId}}"
      app-id="{{appId}}"
      @loaded="onAdLoad" 
      @shown="onAdShown" 
      @clicked="onAdClick" 
      @closed="onAdClose" 
      @empty="onAdEmpty"
      @failed-to-load="onAdFailToLoad"
      @video-complete="onVideoComplete"
    >
    </octopus-ad>
  </div>
</template>

<script>
  import storage from '@system.storage'
  import file from '@system.file'

  export default {
    private: {
      loaded: false,
      appId: '20240327115320',
      adId: '9257',
      muted: false,
      isLoaded: false,
    },
    loadAd() {
      this.$child('ad').load()
    },
    showAd() {
      this.$child('ad').show()
    },
    getIsEmpty() {
      const isEmpty = this.$child('ad').getIsEmpty();
      console.log('isEmpty', isEmpty)
    },
    getPrice() {
      const price = this.$child('ad').getPrice()
      console.log('price', price)
    },
    onAdLoad() {
      this.isLoaded = true
      console.log('onAdLoaded')
    },
    onAdShown() {
      console.log('onAdShown')
    },
    onAdClick() {
      console.log('onAdClicked')
    },
    onAdClose() {
      console.log('onAdClosed')
    },
    onAdEmpty() {
      console.log('onAdEmpty')
    },
    onAdFailToLoad() {
      console.log('onAdFailToLoad')
    },
    preloadVideo() {
      this.$app.$def.preloadVideo(appId || '20240327115320', adId || '9257').then(() => {
        this.loaded = true;
        toast('视频预加载成功')
      })
    }
  }
</script>
```

## 激励视频预加载

sdk 提供`preloadVideo`方法，可预加载一条激励视频广告，展示广告时优先取缓存中的广告物料，若取缓存不成功则请求线上广告。 `preloadAd`方法返回类型是`promise`，可用于判断是否加载成功。

```js
// app.ux

import { preloadVideo } from 'octopus-quickapp-sdk/utils'

export default {
  preloadVideo,
  onCreate() {
  },
}

// 页面中调用
this.$app.$def.preloadVideo(appId, adId).then(() => {
  this.$child('ad').show();
});
```

## 竞胜竞败回传
章鱼广告平台根据媒体传回来的竞胜竞败价格，通过相应算法自动提高出价来获得广告曝光，媒体RTB时一定要调用，否则会导致价格出不上去。

### 代码示例

```js
<import name="octopus-ad" src="octopus-quickapp-sdk/components/index.ux"></import>

<template>
  <div class="page">
    <div class="btn-wrapper">
      <div class="btn" @click="loadAd">
        <text>
          加载广告
        </text>
      </div>
    </div>
    <div if="{{isLoaded}}" class="btn-wrapper">
      <div class="btn" @click="showAd">
        <text>
          显示广告
        </text>
      </div>
    </div>
    <octopus-ad 
      id="ad"
      type="native"
      ad-id="{{adId}}"
      app-id="{{appId}}"
      @loaded="onAdLoad" 
      @shown="onAdShown" 
      @clicked="onAdClick" 
      @closed="onAdClose"
      @failed-to-load="onAdFailToLoad"
    >
    </octopus-ad>
  </div>
</template>

<script>
  export default {
    private: {
      appId: '20240327115320',
      adId: '9258',
      isLoaded: false,
    },
    loadAd() {
      this.$child('ad').load()
    },
    showAd() {
      this.$child('ad').show()
    },
    getPrice() {
      this.$child('ad').getPrice()
    },
    onAdLoad() {
      this.isLoaded = true
      console.log('onAdLoaded')
    },
    sendWinNotice(){
      /* 价格单位为分 */
      // this.$child('ad').setWinNotice(第二高价格)
    },
    sendLossNotice(){
      /* 价格单位为分 */
      /**
       * 竞价失败原因
       * 1001 底价过滤
       * 1002 bid价格低于最高价
       * 1003 素材黑名单过滤
       * 1004 竞品过滤
       * 1005 超时过滤
       * 1006 其它过滤
       */
      /**
       * 竞价胜出者
       * CSJ 穿山甲/头条
       * GDT 优量汇/广点通
       * KUAISHOU 快手
       * BAIDU 百青藤/百度
       * SIGMOB sigmob
       * OPPO oppo
       * VIVO vivo
       * HUAWEI 华为
       * XIAOMI 小米
       * OCTOPUS 章鱼
       * JD 京东
       * QM 趣盟
       * ONEWAY 万唯
       * OTHER 其他家
       */
      // this.$child('ad').sendLossNotice(最高价，竞价失败原因，胜出者)
    },
    onAdShown() {
      console.log('onAdShown')
    },
    onAdClick() {
      console.log('onAdClicked')
    },
    onAdClose() {
      console.log('onAdClosed')
    },
    onAdFailToLoad() {
      console.log('onAdFailToLoad')
    },
  }
</script>
```



