aboutsummaryrefslogtreecommitdiff
path: root/matrix/pushrules/action.go
blob: 4637950d594468705160d98342dedb4473136bec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// gomuks - A terminal Matrix client written in Go.
// Copyright (C) 2019 Tulir Asokan
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

package pushrules

import "encoding/json"

// PushActionType is the type of a PushAction
type PushActionType string

// The allowed push action types as specified in spec section 11.12.1.4.1.
const (
	ActionNotify     PushActionType = "notify"
	ActionDontNotify PushActionType = "dont_notify"
	ActionCoalesce   PushActionType = "coalesce"
	ActionSetTweak   PushActionType = "set_tweak"
)

// PushActionTweak is the type of the tweak in SetTweak push actions.
type PushActionTweak string

// The allowed tweak types as specified in spec section 11.12.1.4.1.1.
const (
	TweakSound     PushActionTweak = "sound"
	TweakHighlight PushActionTweak = "highlight"
)

// PushActionArray is an array of PushActions.
type PushActionArray []*PushAction

// PushActionArrayShould contains the important information parsed from a PushActionArray.
type PushActionArrayShould struct {
	// Whether or not the array contained a Notify, DontNotify or Coalesce action type.
	NotifySpecified bool
	// Whether or not the event in question should trigger a notification.
	Notify bool
	// Whether or not the event in question should be highlighted.
	Highlight bool

	// Whether or not the event in question should trigger a sound alert.
	PlaySound bool
	// The name of the sound to play if PlaySound is true.
	SoundName string
}

// Should parses this push action array and returns the relevant details wrapped in a PushActionArrayShould struct.
func (actions PushActionArray) Should() (should PushActionArrayShould) {
	for _, action := range actions {
		switch action.Action {
		case ActionNotify, ActionCoalesce:
			should.Notify = true
			should.NotifySpecified = true
		case ActionDontNotify:
			should.Notify = false
			should.NotifySpecified = true
		case ActionSetTweak:
			switch action.Tweak {
			case TweakHighlight:
				var ok bool
				should.Highlight, ok = action.Value.(bool)
				if !ok {
					// Highlight value not specified, so assume true since the tweak is set.
					should.Highlight = true
				}
			case TweakSound:
				should.SoundName = action.Value.(string)
				should.PlaySound = len(should.SoundName) > 0
			}
		}
	}
	return
}

// PushAction is a single action that should be triggered when receiving a message.
type PushAction struct {
	Action PushActionType
	Tweak  PushActionTweak
	Value  interface{}
}

// UnmarshalJSON parses JSON into this PushAction.
//
//  * If the JSON is a single string, the value is stored in the Action field.
//  * If the JSON is an object with the set_tweak field, Action will be set to
//    "set_tweak", Tweak will be set to the value of the set_tweak field and
//    and Value will be set to the value of the value field.
//  * In any other case, the function does nothing.
func (action *PushAction) UnmarshalJSON(raw []byte) error {
	var data interface{}

	err := json.Unmarshal(raw, &data)
	if err != nil {
		return err
	}

	switch val := data.(type) {
	case string:
		action.Action = PushActionType(val)
	case map[string]interface{}:
		tweak, ok := val["set_tweak"].(string)
		if ok {
			action.Action = ActionSetTweak
			action.Tweak = PushActionTweak(tweak)
			action.Value, _ = val["value"]
		}
	}
	return nil
}

// MarshalJSON is the reverse of UnmarshalJSON()
func (action *PushAction) MarshalJSON() (raw []byte, err error) {
	if action.Action == ActionSetTweak {
		data := map[string]interface{}{
			"set_tweak": action.Tweak,
			"value":     action.Value,
		}
		return json.Marshal(&data)
	}
	data := string(action.Action)
	return json.Marshal(&data)
}