Compare commits

..

No commits in common. "master" and "v1.0.0" have entirely different histories.

2 changed files with 35 additions and 41 deletions

18
config.toml Normal file
View File

@ -0,0 +1,18 @@
# User Constants - Update as needed
batch_size = 500 # Max 500 messages per batch: https://postmarkapp.com/developer/api/templates-api#send-batch-with-templates
test_email = "" # Fill this in with your own email address
# Handmade Cities Credentials - DON'T TOUCH
[hmc]
api_url = "https://api.handmadecities.com/v1/meetups/subscribers"
shared_secret = "Land_OF_TERminA__MAJORAS_LAIR#666!"
city = "Termina"
# Postmark App Credentials - NO TOUCHY TOUCHY
[postmark]
server_token = "37967b9a-6b1c-430e-a65f-de043de3e568"
api_url = "https://api.postmarkapp.com/email/batchWithTemplates"
template_id = 35682307
sender_name = "Skull Kid"
sender_email = "majora@handmadecities.com"
message_stream = "termina"

58
main.go
View File

@ -7,14 +7,14 @@
// ============================ Contributors ========================= // ============================ Contributors =========================
// Bug & warning fixes // Bug & warning fixes
// Jacob Bell (@MysteriousJ) // Jacob Bell (@MysteriousJ)
// Asaf Gartner (@AsafGartner) // Asaf Gartner
// Joshua Barnett (@jshbrntt)
// Jack Punter (@TarriestPython)
// //
// Emotional Support // Emotional Support
// Cucui Ganon Rosario // Cucui Ganon Rosario
// ========================================================================= // =========================================================================
// WARNING: This program requires a companion config.toml file provided by Abner. Without it we will crash!
package main package main
import ( import (
@ -113,21 +113,15 @@ func retrieveSubscribers(cfg *Config) ([]string, error) {
return nil, errors.New("response format error: 'emails' field not found") return nil, errors.New("response format error: 'emails' field not found")
} }
/* De-duplicate emails using a map */ /* Convert emails to []string */
/* *** */ /* *** */
emailMap := make(map[string]bool) var subscribers []string
for _, email := range emails { for _, email := range emails {
if emailStr, ok := email.(string); ok { if emailStr, ok := email.(string); ok {
emailMap[emailStr] = true subscribers = append(subscribers, emailStr)
} }
} }
/* Convert the map keys back to a slice */
var subscribers []string
for email := range emailMap {
subscribers = append(subscribers, email)
}
return subscribers, nil return subscribers, nil
} }
@ -282,13 +276,6 @@ func blastMail(cfg *Config, logFile string, trackingFile string, audience []stri
} }
} }
existingReaderCount := len(sentToAddresses)
newReaderCount := 0
if existingReaderCount > 0 {
fmt.Println("Same email file specified: Sending only to new subscribers...")
}
var group []string var group []string
for _, a := range audience { for _, a := range audience {
if a == "" { if a == "" {
@ -314,7 +301,6 @@ func blastMail(cfg *Config, logFile string, trackingFile string, audience []stri
for i, res := range results { for i, res := range results {
log.WriteString(fmt.Sprintf("%s: %s\n", group[i], res.Message)) log.WriteString(fmt.Sprintf("%s: %s\n", group[i], res.Message))
} }
newReaderCount += len(group)
group = group[0:0] group = group[0:0]
} }
} }
@ -330,16 +316,6 @@ func blastMail(cfg *Config, logFile string, trackingFile string, audience []stri
for i, res := range results { for i, res := range results {
log.WriteString(fmt.Sprintf("%s: %s\n", group[i], res.Message)) log.WriteString(fmt.Sprintf("%s: %s\n", group[i], res.Message))
} }
newReaderCount += len(group)
}
if newReaderCount > 0 {
newSubscribers := existingReaderCount > 0
if newSubscribers {
fmt.Printf("Sent to %d new subscribers!\n", newReaderCount)
}
} else {
fmt.Printf("Not sent (no new subscribers)\n")
} }
} }
@ -487,10 +463,10 @@ func main() {
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
fmt.Printf(`Instructions: fmt.Printf(`Instructions:
1. Create an email file 1. Create an email file
* Call it whatever you want. Markdown format is expected * Name it whatever you want. Markdown is expected
* Newlines at the beginning and end will be trimmed * Any newlines at the start or end of the file will be removed
* The first line is your email subject. It MUST start with the # symbol * The first line of the file will be used as {{ subject }} in the postmark template. It must start with the # symbol
* The rest of the file is your email's body * The rest of the file will be used as {{{ content_body }}}
2. See who's subscribed 2. See who's subscribed
* ./meetupinvite2000 dump * ./meetupinvite2000 dump
@ -499,15 +475,15 @@ func main() {
3. Do a test run 3. Do a test run
* ./meetupinvite2000 test [email file] * ./meetupinvite2000 test [email file]
* You must send a test before blasting to everyone (please update config.toml to change test recipient) * You must send a test email before blasting it to everyone (update config.toml to change test recipient)
* If you modify the email after testing, you must test again. Otherwise we will complain * If you modify the email file after testing, you must test again. Otherwise MeetupInvite2000 will complain
4. Start blasting! 4. Start blasting!
* ./meetupinvite2000 blast [email file] * ./meetupinvite2000 blast [email file]
* Batch sends your invite using our Email API (Postmark) * Will batch send your invite using our Email API (Postmark)
* Produces .track file that tracks email addresses we attempted to send to * Will produce a .track file that will list all email addresses that we attempted to send to
* Produces .log file with information received back from Postmark * In case of error, you can blast again. All emails listed in the .track file will be skipped
* In case of errors, you can always blast again. Addresses already in .track file will be skipped * Will produce a .log file with information received back from Postmark
`) `)
}, },
} }
@ -529,7 +505,7 @@ func main() {
indexStr = strings.Repeat(" ", maxIndexWidth-len(indexStr)) + indexStr // Right-align the index indexStr = strings.Repeat(" ", maxIndexWidth-len(indexStr)) + indexStr // Right-align the index
fmt.Printf("%s. \033[1m%s\033[0m\n", indexStr, email) fmt.Printf("%s. \033[1m%s\033[0m\n", indexStr, email)
} }
fmt.Printf("\nMailing list grows automatically as more subscribe at \033[1mhandmadecities.com/meetups/%s\033[0m\n", config.Postmark.MessageStream) fmt.Printf("\nMailing list grows automatically as more subscribe at \033[1mhandmadecities.com/meetups\033[0m\n")
}, },
} }