github.com/sharovik/devbot@v1.0.1-0.20240308094637-4a0387c40516/events/repeatevent/event.go (about) 1 package repeatevent 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "github.com/sharovik/devbot/internal/service/message/conversation" 9 "github.com/sharovik/devbot/internal/service/schedule" 10 11 "github.com/sharovik/devbot/internal/container" 12 "github.com/sharovik/devbot/internal/database" 13 "github.com/sharovik/devbot/internal/dto" 14 "github.com/sharovik/devbot/internal/dto/databasedto" 15 "github.com/sharovik/devbot/internal/log" 16 "github.com/sharovik/orm/clients" 17 cdto "github.com/sharovik/orm/dto" 18 "github.com/sharovik/orm/query" 19 ) 20 21 const ( 22 //EventName the name of the event 23 EventName = "repeatevent" 24 25 //EventVersion the version of the event 26 EventVersion = "1.0.0" 27 28 helpMessage = "Ask me `repeat` and I will try repeat again the event I previously executed by your command. Eg: You ask me to run something and then you need to rerun in again. You write repeat and I repeat the event." 29 ) 30 31 // EventStruct the struct for the event object. It will be used for initialisation of the event in defined-events.go file. 32 type EventStruct struct { 33 } 34 35 // Event - object which is ready to use 36 var ( 37 Event = EventStruct{} 38 ) 39 40 // Help retrieves the help message 41 func (e EventStruct) Help() string { 42 return helpMessage 43 } 44 45 // Alias retrieves the event alias 46 func (e EventStruct) Alias() string { 47 return EventName 48 } 49 50 // Execute method which is called by message processor 51 func (e EventStruct) Execute(message dto.BaseChatMessage) (dto.BaseChatMessage, error) { 52 executedEvent, err := lastExecutedEvent(message) 53 if err != nil { 54 message.Text = "Failed to fetch the last executed events for that channel." 55 return message, err 56 } 57 58 if executedEvent.GetField("id").Value == nil { 59 message.Text = "It looks like you didn't executed any event yet at this channel." 60 return message, nil 61 } 62 63 answer, err := triggerScenario(executedEvent) 64 if err != nil { 65 message.Text = fmt.Sprintf("Failed to execute the event.\n```%s```", err) 66 return message, err 67 } 68 69 message.Text = answer.Text 70 return message, nil 71 } 72 73 func getRepeatEventID() (int64, error) { 74 eventID, err := container.C.Dictionary.FindEventByAlias(EventName) 75 if err != nil { 76 return 0, err 77 } 78 79 return eventID, nil 80 } 81 82 // Install method for installation of event 83 func (e EventStruct) Install() error { 84 log.Logger().Debug(). 85 Str("event_name", EventName). 86 Str("event_version", EventVersion). 87 Msg("Triggered event installation") 88 89 return container.C.Dictionary.InstallNewEventScenario(database.EventScenario{ 90 EventName: EventName, 91 EventVersion: EventVersion, 92 Questions: []database.Question{ 93 { 94 Question: "repeat", 95 Answer: "one sec", 96 QuestionRegex: "(?i)repeat", 97 QuestionGroup: "", 98 }, 99 }, 100 }) 101 } 102 103 func lastExecutedEvent(message dto.BaseChatMessage) (cdto.ModelInterface, error) { 104 currentEventID, err := getRepeatEventID() 105 if err != nil { 106 return nil, err 107 } 108 109 item, err := container.C.Dictionary.GetDBClient().Execute(new(clients.Query). 110 Select([]interface{}{}).From(databasedto.EventTriggerHistoryModel). 111 Where(query.Where{ 112 First: "channel", 113 Operator: "=", 114 Second: query.Bind{ 115 Field: "channel", 116 Value: message.Channel, 117 }, 118 }).Where(query.Where{ 119 First: "user", 120 Operator: "=", 121 Second: query.Bind{ 122 Field: "user", 123 Value: message.OriginalMessage.User, 124 }, 125 }).Where(query.Where{ 126 First: "event_id", 127 Operator: "<>", 128 Second: query.Bind{ 129 Field: "event_id", 130 Value: currentEventID, 131 }, 132 }).OrderBy("id", query.OrderDirectionDesc).Limit(query.Limit{ 133 From: 0, 134 To: 1, 135 })) 136 137 if err != nil { 138 return nil, err 139 } 140 141 if len(item.Items()) == 0 { 142 return nil, nil 143 } 144 145 model := databasedto.EventTriggerHistoryModel 146 147 for _, field := range item.Items()[0].GetColumns() { 148 switch f := field.(type) { 149 case cdto.ModelField: 150 model.AddModelField(cdto.ModelField{ 151 Name: f.Name, 152 Value: f.Value, 153 }) 154 default: 155 continue 156 } 157 158 } 159 160 return model, nil 161 } 162 163 func getEventAliasByID(eventID int) (string, error) { 164 item, err := container.C.Dictionary.GetDBClient().Execute(new(clients.Query). 165 Select([]interface{}{"alias"}).From(databasedto.EventModel).Where(query.Where{ 166 First: "id", 167 Operator: "=", 168 Second: query.Bind{ 169 Field: "id", 170 Value: eventID, 171 }, 172 })) 173 if err != nil { 174 return "", err 175 } 176 177 if len(item.Items()) == 0 { 178 return "", fmt.Errorf("failed to find the event alias for selected ID") 179 } 180 181 return item.Items()[0].GetField("alias").Value.(string), nil 182 } 183 184 func triggerScenario(item cdto.ModelInterface) (dto.BaseChatMessage, error) { 185 eventAlias, err := getEventAliasByID(item.GetField("event_id").Value.(int)) 186 if err != nil { 187 return dto.BaseChatMessage{}, err 188 } 189 190 var ( 191 variables []string 192 channel = item.GetField("channel").Value.(string) 193 ) 194 195 if item.GetField("variables").Value.(string) != "" { 196 scenario := database.EventScenario{ 197 RequiredVariables: nil, 198 } 199 200 variables = strings.Split(item.GetField("variables").Value.(string), schedule.VariablesDelimiter) 201 for _, variable := range variables { 202 scenario.RequiredVariables = append(scenario.RequiredVariables, database.ScenarioVariable{ 203 Value: variable, 204 }) 205 } 206 207 dmAnswer := dto.DictionaryMessage{ 208 ScenarioID: int64(item.GetField("scenario_id").Value.(int)), 209 Question: item.GetField("command").Value.(string), 210 QuestionID: int64(item.GetField("last_question_id").Value.(int)), 211 EventID: int64(item.GetField("event_id").Value.(int)), 212 ReactionType: eventAlias, 213 } 214 215 conversation.AddConversation(scenario, dto.BaseChatMessage{ 216 Channel: channel, 217 Text: item.GetField("command").Value.(string), 218 AsUser: false, 219 Ts: time.Now(), 220 DictionaryMessage: dmAnswer, 221 OriginalMessage: dto.BaseOriginalMessage{}, 222 }) 223 224 return container.C.DefinedEvents[eventAlias].Execute(conversation.GetConversation(channel).LastQuestion) 225 } 226 227 return container.C.DefinedEvents[eventAlias].Execute(dto.BaseChatMessage{ 228 Channel: channel, 229 Text: item.GetField("command").Value.(string), 230 AsUser: false, 231 Ts: time.Time{}, 232 DictionaryMessage: dto.DictionaryMessage{ 233 ScenarioID: int64(item.GetField("scenario_id").Value.(int)), 234 Question: "", 235 QuestionID: int64(item.GetField("last_question_id").Value.(int)), 236 EventID: int64(item.GetField("event_id").Value.(int)), 237 }, 238 OriginalMessage: dto.BaseOriginalMessage{ 239 Text: item.GetField("command").Value.(string), 240 User: item.GetField("user").Value.(string), 241 Files: nil, 242 }, 243 }) 244 } 245 246 // Update for event update actions 247 func (e EventStruct) Update() error { 248 return nil 249 }