func (o *oneSignalDrv) Send(ctx context.Context, message *notificationpb.Message, man template.Manager, ch chan<- drivers.DriverResult) {
	p := message.GetPush()
	m := o.notification()
	if uid, ok := message.Tags["user_id"]; ok {
		m.addTagFilter("userid", uid)
	} else if len(p.To) > 0 {
		m.addTagFilter("userid", p.To[0])
	}

	if env, ok := message.Tags["env"]; ok {
		m.addTagFilter("env", env)
	}
	if len(p.To) > 0 {
		m.IncludePlayerIDs = p.To
	}
	if message.ScheduleAt > 0 {
		m.SendAfter = time.Unix(message.ScheduleAt, 0).UTC().String()
	}
	if p.LaunchUrl > "" {
		m.Url = p.LaunchUrl
	}
	if err := putContent(&m, message, man); err != nil {
		ch <- drivers.DriverResult{Type: drivers.TypePush, Err: err}
		return
	}

	var out bytes.Buffer
	if err := json.NewEncoder(&out).Encode(&m); err != nil {
		ch <- drivers.DriverResult{Type: drivers.TypePush, Err: fmt.Errorf("encode message json error, %v", err)}
		return
	}
	req, err := http.NewRequest("POST", "https://onesignal.com/api/v1/notifications", &out)
	if err != nil {
		ch <- drivers.DriverResult{Type: drivers.TypePush, Err: err}
		return
	}
	req.Header.Set("Authorization", fmt.Sprintf("Basic %s", o.authorization))
	req.Header.Set("Content-Type", "application/json")
	select {
	case <-ctx.Done():
		ch <- drivers.DriverResult{Type: drivers.TypePush, Err: ctx.Err()}
		return
	default:
	}
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		ch <- drivers.DriverResult{Type: drivers.TypePush, Err: err}
		return
	}
	if resp.StatusCode != http.StatusOK {
		ch <- drivers.DriverResult{Type: drivers.TypePush, Err: fmt.Errorf("status code: %d", resp.StatusCode)}
		return
	}
	ch <- drivers.DriverResult{Type: drivers.TypePush, Err: nil}
}
func putContent(n *notification, message *notificationpb.Message, man template.Manager) error {
	p := message.GetPush()
	langs := man.Languages(message.Event, "push")
	data := make(map[string]interface{})
	if err := json.Unmarshal(message.DataJson, &data); err != nil {
		return err
	}
	for k, v := range message.Tags {
		if _, ok := data[k]; !ok {
			data[k] = v
		}
	}
	for _, l := range langs {
		t, err := man.Template(message.Event, l, "push")
		if err != nil {
			return err
		}
		s, err := t.String(data)
		if err != nil {
			return err
		}
		n.Contents[l] = s
	}

	for _, l := range man.Languages(message.Event, "tit") {
		t, err := man.Template(message.Event, l, "tit")
		if err != nil {
			return err
		}
		s, err := t.String(data)
		if err != nil {
			return err
		}
		n.Headings[l] = s
	}

	if len(p.Template) > 0 {
		cts := make(map[string]string)
		if err := json.Unmarshal(p.Template, &cts); err != nil {
			if len(langs) == 0 {
				t, e := template.NewTemplate(string(p.Template), false)
				if e != nil {
					return e
				}
				s, _ := t.String(data)
				n.Contents["en"] = s
				n.Contents[message.Language] = s
				return nil
			}
		} else {
			for k, v := range cts {
				t, e := template.NewTemplate(v, false)
				if e != nil {
					continue
				}
				n.Contents[k], _ = t.String(data)
			}
			if _, ok := n.Contents["en"]; !ok {
				n.Contents["en"] = ""
			}
			return nil
		}
	}
	if len(p.Headings) > 0 {
		cts := make(map[string]string)
		if err := json.Unmarshal(p.Template, &cts); err != nil {
			if len(langs) == 0 {
				t, e := template.NewTemplate(string(p.Template), false)
				if e != nil {
					return e
				}
				s, _ := t.String(data)
				n.Headings["en"] = s
				n.Headings[message.Language] = s
				return nil
			}
		} else {
			for k, v := range cts {
				t, e := template.NewTemplate(v, false)
				if e != nil {
					continue
				}
				n.Headings[k], _ = t.String(data)
			}
			if _, ok := n.Headings["en"]; !ok {
				n.Headings["en"] = ""
			}
			return nil
		}
	}
	return nil
}