github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/plugins/slack/actor.go (about)

     1  // This file is part of the Smart Home
     2  // Program complex distribution https://github.com/e154/smart-home
     3  // Copyright (C) 2016-2023, Filippov Alex
     4  //
     5  // This library is free software: you can redistribute it and/or
     6  // modify it under the terms of the GNU Lesser General Public
     7  // License as published by the Free Software Foundation; either
     8  // version 3 of the License, or (at your option) any later version.
     9  //
    10  // This library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13  // Library General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public
    16  // License along with this library.  If not, see
    17  // <https://www.gnu.org/licenses/>.
    18  
    19  package slack
    20  
    21  import (
    22  	"context"
    23  	"strings"
    24  
    25  	"github.com/nlopes/slack"
    26  
    27  	"github.com/e154/smart-home/common/apperr"
    28  	m "github.com/e154/smart-home/models"
    29  	"github.com/e154/smart-home/plugins/notify"
    30  	"github.com/e154/smart-home/plugins/notify/common"
    31  	"github.com/e154/smart-home/system/supervisor"
    32  )
    33  
    34  // Actor ...
    35  type Actor struct {
    36  	*supervisor.BaseActor
    37  	notify   *notify.Notify
    38  	Token    string
    39  	UserName string
    40  	api      *slack.Client
    41  }
    42  
    43  // NewActor ...
    44  func NewActor(entity *m.Entity,
    45  	service supervisor.Service) *Actor {
    46  
    47  	token := entity.Settings[AttrToken].Decrypt()
    48  
    49  	actor := &Actor{
    50  		BaseActor: supervisor.NewBaseActor(entity, service),
    51  		notify:    notify.NewNotify(service.Adaptors()),
    52  		UserName:  entity.Settings[AttrUserName].String(),
    53  		Token:     token,
    54  		api:       slack.New(token),
    55  	}
    56  
    57  	return actor
    58  }
    59  
    60  func (e *Actor) Destroy() {
    61  	e.Service.EventBus().Unsubscribe(notify.TopicNotify, e.eventHandler)
    62  	e.notify.Shutdown()
    63  }
    64  
    65  func (e *Actor) Spawn() {
    66  	e.notify.Start()
    67  	e.Service.EventBus().Subscribe(notify.TopicNotify, e.eventHandler, false)
    68  }
    69  
    70  // Save ...
    71  func (e *Actor) Save(msg common.Message) (addresses []string, message *m.Message) {
    72  	message = &m.Message{
    73  		Type:       Name,
    74  		Attributes: msg.Attributes,
    75  	}
    76  	var err error
    77  	if message.Id, err = e.Service.Adaptors().Message.Add(context.Background(), message); err != nil {
    78  		log.Error(err.Error())
    79  	}
    80  
    81  	attr := NewAttr()
    82  	_, _ = attr.Deserialize(message.Attributes)
    83  
    84  	addresses = strings.Split(attr[AttrChannel].String(), ",")
    85  	return
    86  }
    87  
    88  // Send ...
    89  func (e *Actor) Send(address string, message *m.Message) (err error) {
    90  
    91  	if e.Token == "" || e.UserName == "" {
    92  		return apperr.ErrBadActorSettingsParameters
    93  	}
    94  
    95  	attr := NewAttr()
    96  	_, _ = attr.Deserialize(message.Attributes)
    97  
    98  	options := []slack.MsgOption{
    99  		slack.MsgOptionText(attr[AttrText].String(), false),
   100  	}
   101  
   102  	if e.UserName != "" {
   103  		options = append(options, slack.MsgOptionUsername(e.UserName))
   104  	}
   105  
   106  	var channelID, timestamp string
   107  	if channelID, timestamp, err = e.api.PostMessage(address, options...); err != nil {
   108  		log.Error(err.Error())
   109  		return
   110  	}
   111  	log.Infof("Message successfully sent to channel '%s' at '%s'", channelID, timestamp)
   112  
   113  	return
   114  }
   115  
   116  // MessageParams ...
   117  // Channel
   118  // Text
   119  func (e *Actor) MessageParams() m.Attributes {
   120  	return NewAttr()
   121  }
   122  
   123  func (e *Actor) eventHandler(_ string, event interface{}) {
   124  
   125  	switch v := event.(type) {
   126  	case common.Message:
   127  		if v.EntityId != nil && *v.EntityId == e.Id {
   128  			e.notify.SaveAndSend(v, e)
   129  		}
   130  	}
   131  }