Added support for creating slack channels with reference to a weekday, added support for specifying users to always add to a channel, maybe more?
This commit is contained in:
parent
e6ef66194e
commit
2354e60b3d
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
config.yaml
|
config.yaml
|
||||||
service-notifications
|
service-notifications
|
||||||
service-notifications.db
|
service-notifications.db
|
||||||
|
sync.sh
|
@ -110,6 +110,7 @@ Get Slack API token by creating an app at https://api.slack.com/apps then go to
|
|||||||
|
|
||||||
Get Planning Center API secrets at https://api.planningcenteronline.com/oauth/applications by creating a personal access token.
|
Get Planning Center API secrets at https://api.planningcenteronline.com/oauth/applications by creating a personal access token.
|
||||||
|
|
||||||
|
You can get a slack user ID by viewing the profile and under the 3 dot menu choose Copy member ID.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
@ -122,6 +123,9 @@ planning_center:
|
|||||||
|
|
||||||
slack:
|
slack:
|
||||||
api_token: SLACK_API_TOKEN
|
api_token: SLACK_API_TOKEN
|
||||||
admin_id: SLACK_UID
|
create_from_weekday: 3
|
||||||
|
default_conversation: SLACK_UID
|
||||||
|
sticky_users:
|
||||||
|
- SLACK_UID
|
||||||
|
|
||||||
```
|
```
|
2
api.go
2
api.go
@ -96,7 +96,7 @@ func (s *HTTPServer) RegisterAPIRoutes(r *mux.Router) {
|
|||||||
|
|
||||||
// Get current time and default conversation.
|
// Get current time and default conversation.
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
conversation := app.config.Slack.AdminID
|
conversation := app.config.Slack.DefaultConversation
|
||||||
|
|
||||||
// Find plan times that are occuring right now.
|
// Find plan times that are occuring right now.
|
||||||
var planTime PlanTimes
|
var planTime PlanTimes
|
||||||
|
@ -35,9 +35,11 @@ type PlanningCenterConfig struct {
|
|||||||
|
|
||||||
// Configurations relating to Slack API/channel creation.
|
// Configurations relating to Slack API/channel creation.
|
||||||
type SlackConfig struct {
|
type SlackConfig struct {
|
||||||
|
CreateFromWeekday int `fig:"create_from_weekday"` // Create ahead from this weekday. -1 value is default and will instead create from the current time of operation.
|
||||||
CreateChannelsAhead time.Duration `fig:"create_channels_ahead"` // Amount of time of future services to create channels head for. Defaults to 8 days head.
|
CreateChannelsAhead time.Duration `fig:"create_channels_ahead"` // Amount of time of future services to create channels head for. Defaults to 8 days head.
|
||||||
APIToken string `fig:"api_token"`
|
APIToken string `fig:"api_token"`
|
||||||
AdminID string `fig:"admin_id"` // Slack user that administers this app.
|
StickyUsers []string `fig:"sticky_users"` // Users to add to every channel.
|
||||||
|
DefaultConversation string `fig:"default_conversation"` // Slack user that administers this app.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configuration Structure.
|
// Configuration Structure.
|
||||||
@ -86,6 +88,7 @@ func (a *App) ReadConfig() {
|
|||||||
Connection: "service-notifications.db",
|
Connection: "service-notifications.db",
|
||||||
},
|
},
|
||||||
Slack: SlackConfig{
|
Slack: SlackConfig{
|
||||||
|
CreateFromWeekday: -1,
|
||||||
CreateChannelsAhead: time.Hour * 24 * 8,
|
CreateChannelsAhead: time.Hour * 24 * 8,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
2
main.go
2
main.go
@ -13,7 +13,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
serviceName = "service-notifications"
|
serviceName = "service-notifications"
|
||||||
serviceDescription = "Notifications for church services"
|
serviceDescription = "Notifications for church services"
|
||||||
serviceVersion = "0.1"
|
serviceVersion = "0.2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// App is the global application structure for communicating between servers and storing information.
|
// App is the global application structure for communicating between servers and storing information.
|
||||||
|
85
update.go
85
update.go
@ -13,6 +13,19 @@ import (
|
|||||||
|
|
||||||
// Update planning center database tables with data from PC API.
|
// Update planning center database tables with data from PC API.
|
||||||
func UpdatePCData() {
|
func UpdatePCData() {
|
||||||
|
// We don't need to update the archive if we already have data from the past,
|
||||||
|
// as such we get the current time and see if we already have an entry in the future.
|
||||||
|
// Its possible that some people only schedule services once a week, so we check with
|
||||||
|
// the current date subtracted by 14 days.
|
||||||
|
var updateFrom time.Time
|
||||||
|
now := time.Now().UTC()
|
||||||
|
var futurePlan Plans
|
||||||
|
app.db.Where("first_time_at >= ?", now.Add(time.Hour*24*14*-1)).Order("first_time_at ASC").First(&futurePlan)
|
||||||
|
if futurePlan.ID != 0 {
|
||||||
|
// If a future plan exists, we update from past 30 days.
|
||||||
|
updateFrom = now.Add(time.Hour * 24 * 30 * -1)
|
||||||
|
}
|
||||||
|
|
||||||
// Get all people.
|
// Get all people.
|
||||||
allPeople, err := PCGetAll("/services/v2/people")
|
allPeople, err := PCGetAll("/services/v2/people")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -118,6 +131,13 @@ func UpdatePCData() {
|
|||||||
p.MultiDay = attributes.GetBool("multi_day")
|
p.MultiDay = attributes.GetBool("multi_day")
|
||||||
p.Dates = attributes.GetString("dates")
|
p.Dates = attributes.GetString("dates")
|
||||||
|
|
||||||
|
// If either updated at or first time at for the plan is before the update from date,
|
||||||
|
// we can process the update of data. Otherwise, we ignore this service as we do not care
|
||||||
|
// about updating historic data. Updating historic data causes more API traffic than needed.
|
||||||
|
if p.UpdatedAt.Before(updateFrom) && p.FirstTimeAt.Before(updateFrom) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// If plan wasn't already created, create it.
|
// If plan wasn't already created, create it.
|
||||||
if p.ID == 0 {
|
if p.ID == 0 {
|
||||||
p.ID = planID
|
p.ID = planID
|
||||||
@ -291,13 +311,41 @@ func UpdateSlackData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Delay on channel descript/topic may not be long enough.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
// Create slack channels for upcoming services.
|
// Create slack channels for upcoming services.
|
||||||
func CreateSlackChannels() {
|
func CreateSlackChannels() {
|
||||||
// For now, we're using the start time of now. I want to update this later to allow
|
// Start at now.
|
||||||
// setting a day of the week for slack channels to be created on.
|
now := time.Now().UTC()
|
||||||
// Doing a day of the week will allow for channels to be created ahead of time, then
|
startDate := now
|
||||||
// if people are added to the plan later on, they can be added at the next cron run.
|
// If create from weekday is a valid weekday, attempt to turn back the clock to the
|
||||||
startDate := time.Now().UTC()
|
// most recently past weekday. Use that day as the stating point so we do not
|
||||||
|
// create channels in the future past the date we expect to have channels.
|
||||||
|
// This is useful if you want to run the cron every day to keep channel title
|
||||||
|
// and members up to date, but only want so many channels ahead of a certain weekday.
|
||||||
|
if app.config.Slack.CreateFromWeekday != -1 && app.config.Slack.CreateFromWeekday <= 6 {
|
||||||
|
// Get the current weekday and set the days to subtract to 0.
|
||||||
|
thisWeekday := int(now.Weekday())
|
||||||
|
var daysSub int = 0
|
||||||
|
|
||||||
|
// If this weekday is the day we intend to create from, or if the weekday is
|
||||||
|
// after. We want to just subtract this weekday from create form weekday which
|
||||||
|
// should get us back to the most recent weekday.
|
||||||
|
if thisWeekday >= app.config.Slack.CreateFromWeekday {
|
||||||
|
daysSub = app.config.Slack.CreateFromWeekday - thisWeekday
|
||||||
|
} else {
|
||||||
|
// Otherwise, we have started a new week from that weekday and we need to
|
||||||
|
// add 7 days to the current weekday in our subtraction. This will bring us
|
||||||
|
// not to the next weekday, but the past weekday.
|
||||||
|
daysSub = app.config.Slack.CreateFromWeekday - (thisWeekday + 7)
|
||||||
|
}
|
||||||
|
// Subtract the number of days calculated to bring us to the weekday to create form.
|
||||||
|
startDate = now.Add(time.Hour * 24 * time.Duration(daysSub))
|
||||||
|
}
|
||||||
// Last date is start date plus duration of create channels ahead.
|
// Last date is start date plus duration of create channels ahead.
|
||||||
lastDate := startDate.Add(app.config.Slack.CreateChannelsAhead)
|
lastDate := startDate.Add(app.config.Slack.CreateChannelsAhead)
|
||||||
|
|
||||||
@ -391,7 +439,7 @@ func CreateSlackChannels() {
|
|||||||
if topic != "" {
|
if topic != "" {
|
||||||
// Sleep before, as it takes time for Slack APIs
|
// Sleep before, as it takes time for Slack APIs
|
||||||
// to recongize the channel was created.
|
// to recongize the channel was created.
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(120 * time.Second)
|
||||||
_, err = app.slack.SetTopicOfConversation(channel.ID, topic)
|
_, err = app.slack.SetTopicOfConversation(channel.ID, topic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Failed to set topic:", err)
|
log.Println("Failed to set topic:", err)
|
||||||
@ -421,6 +469,31 @@ func CreateSlackChannels() {
|
|||||||
// Keep a list of users we need to invite as they are new.
|
// Keep a list of users we need to invite as they are new.
|
||||||
var usersToInvite []string
|
var usersToInvite []string
|
||||||
|
|
||||||
|
// For each sticky user, invite them.
|
||||||
|
for _, stickyUser := range app.config.Slack.StickyUsers {
|
||||||
|
// Check if they were already invited.
|
||||||
|
alreadyInvited := false
|
||||||
|
for _, uid := range invited {
|
||||||
|
if uid == stickyUser {
|
||||||
|
alreadyInvited = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure they were not already added to the list of users.
|
||||||
|
for _, uid := range usersToInvite {
|
||||||
|
if uid == stickyUser {
|
||||||
|
alreadyInvited = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not already invited, add to the list of users to invite.
|
||||||
|
if !alreadyInvited {
|
||||||
|
usersToInvite = append(usersToInvite, stickyUser)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For each person on the plan, see if we need to invite them.
|
// For each person on the plan, see if we need to invite them.
|
||||||
for _, personOnPlan := range peopleOnPlan {
|
for _, personOnPlan := range peopleOnPlan {
|
||||||
// Find the slack user for the planning center person.
|
// Find the slack user for the planning center person.
|
||||||
|
Loading…
Reference in New Issue
Block a user