mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 09:00:10 +00:00
Telegram: Send messages via telegram
Most messages are now sent as plaintext via telegram when suitable.
This commit is contained in:
parent
72bf280e2d
commit
716d6a931a
104
api.go
104
api.go
@ -282,7 +282,7 @@ func (app *appContext) NewUserAdmin(gc *gin.Context) {
|
||||
}
|
||||
}
|
||||
app.jf.CacheExpiry = time.Now()
|
||||
if app.config.Section("password_resets").Key("enabled").MustBool(false) {
|
||||
if emailEnabled {
|
||||
app.storage.emails[id] = req.Email
|
||||
app.storage.storeEmails()
|
||||
}
|
||||
@ -500,15 +500,16 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc
|
||||
}
|
||||
}
|
||||
|
||||
if emailEnabled && app.config.Section("welcome_email").Key("enabled").MustBool(false) && req.Email != "" {
|
||||
app.debug.Printf("%s: Sending welcome email to %s", req.Username, req.Email)
|
||||
if (emailEnabled && app.config.Section("welcome_email").Key("enabled").MustBool(false) && req.Email != "") || telegramTokenIndex != -1 {
|
||||
name := app.getAddressOrName(user.ID)
|
||||
app.debug.Printf("%s: Sending welcome message to %s", req.Username, name)
|
||||
msg, err := app.email.constructWelcome(req.Username, expiry, app, false)
|
||||
if err != nil {
|
||||
app.err.Printf("%s: Failed to construct welcome email: %v", req.Username, err)
|
||||
} else if err := app.email.send(msg, req.Email); err != nil {
|
||||
app.err.Printf("%s: Failed to send welcome email: %v", req.Username, err)
|
||||
app.err.Printf("%s: Failed to construct welcome message: %v", req.Username, err)
|
||||
} else if err := app.sendByID(msg, user.ID); err != nil {
|
||||
app.err.Printf("%s: Failed to send welcome message: %v", req.Username, err)
|
||||
} else {
|
||||
app.info.Printf("%s: Sent welcome email to \"%s\"", req.Username, req.Email)
|
||||
app.info.Printf("%s: Sent welcome message to \"%s\"", req.Username, name)
|
||||
}
|
||||
}
|
||||
app.jf.CacheExpiry = time.Now()
|
||||
@ -575,7 +576,20 @@ func (app *appContext) EnableDisableUsers(gc *gin.Context) {
|
||||
"GetUser": map[string]string{},
|
||||
"SetPolicy": map[string]string{},
|
||||
}
|
||||
var addresses []string
|
||||
sendMail := emailEnabled || app.config.Section("telegram").Key("enabled").MustBool(false)
|
||||
var msg *Message
|
||||
var err error
|
||||
if sendMail {
|
||||
if req.Enabled {
|
||||
msg, err = app.email.constructEnabled(req.Reason, app, false)
|
||||
} else {
|
||||
msg, err = app.email.constructDisabled(req.Reason, app, false)
|
||||
}
|
||||
if err != nil {
|
||||
app.err.Printf("Failed to construct account enabled/disabled emails: %v", err)
|
||||
sendMail = false
|
||||
}
|
||||
}
|
||||
for _, userID := range req.Users {
|
||||
user, status, err := app.jf.UserByID(userID, false)
|
||||
if status != 200 || err != nil {
|
||||
@ -590,31 +604,13 @@ func (app *appContext) EnableDisableUsers(gc *gin.Context) {
|
||||
app.err.Printf("Failed to set policy for user \"%s\" (%d): %v", userID, status, err)
|
||||
continue
|
||||
}
|
||||
if emailEnabled && req.Notify {
|
||||
addr, ok := app.storage.emails[userID]
|
||||
if addr != nil && ok {
|
||||
addresses = append(addresses, addr.(string))
|
||||
if sendMail && req.Notify {
|
||||
if err := app.sendByID(msg, userID); err != nil {
|
||||
app.err.Printf("Failed to send account enabled/disabled email: %v", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(addresses) != 0 {
|
||||
go func(reason string, addresses []string) {
|
||||
var msg *Message
|
||||
var err error
|
||||
if req.Enabled {
|
||||
msg, err = app.email.constructEnabled(reason, app, false)
|
||||
} else {
|
||||
msg, err = app.email.constructDisabled(reason, app, false)
|
||||
}
|
||||
if err != nil {
|
||||
app.err.Printf("Failed to construct account enabled/disabled emails: %v", err)
|
||||
} else if err := app.email.send(msg, addresses...); err != nil {
|
||||
app.err.Printf("Failed to send account enabled/disabled emails: %v", err)
|
||||
} else {
|
||||
app.info.Println("Sent account enabled/disabled emails")
|
||||
}
|
||||
}(req.Reason, addresses)
|
||||
}
|
||||
app.jf.CacheExpiry = time.Now()
|
||||
if len(errors["GetUser"]) != 0 || len(errors["SetPolicy"]) != 0 {
|
||||
gc.JSON(500, errors)
|
||||
@ -634,10 +630,19 @@ func (app *appContext) EnableDisableUsers(gc *gin.Context) {
|
||||
// @tags Users
|
||||
func (app *appContext) DeleteUsers(gc *gin.Context) {
|
||||
var req deleteUserDTO
|
||||
var addresses []string
|
||||
gc.BindJSON(&req)
|
||||
errors := map[string]string{}
|
||||
ombiEnabled := app.config.Section("ombi").Key("enabled").MustBool(false)
|
||||
sendMail := emailEnabled || app.config.Section("telegram").Key("enabled").MustBool(false)
|
||||
var msg *Message
|
||||
var err error
|
||||
if sendMail {
|
||||
msg, err = app.email.constructDeleted(req.Reason, app, false)
|
||||
if err != nil {
|
||||
app.err.Printf("Failed to construct account deletion emails: %v", err)
|
||||
sendMail = false
|
||||
}
|
||||
}
|
||||
for _, userID := range req.Users {
|
||||
if ombiEnabled {
|
||||
ombiUser, code, err := app.getOmbiUser(userID)
|
||||
@ -660,25 +665,12 @@ func (app *appContext) DeleteUsers(gc *gin.Context) {
|
||||
errors[userID] += msg
|
||||
}
|
||||
}
|
||||
if emailEnabled && req.Notify {
|
||||
addr, ok := app.storage.emails[userID]
|
||||
if addr != nil && ok {
|
||||
addresses = append(addresses, addr.(string))
|
||||
if sendMail && req.Notify {
|
||||
if err := app.sendByID(msg, userID); err != nil {
|
||||
app.err.Printf("Failed to send account deletion email: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(addresses) != 0 {
|
||||
go func(reason string, addresses []string) {
|
||||
msg, err := app.email.constructDeleted(reason, app, false)
|
||||
if err != nil {
|
||||
app.err.Printf("Failed to construct account deletion emails: %v", err)
|
||||
} else if err := app.email.send(msg, addresses...); err != nil {
|
||||
app.err.Printf("Failed to send account deletion emails: %v", err)
|
||||
} else {
|
||||
app.info.Println("Sent account deletion emails")
|
||||
}
|
||||
}(req.Reason, addresses)
|
||||
}
|
||||
app.jf.CacheExpiry = time.Now()
|
||||
if len(errors) == len(req.Users) {
|
||||
respondBool(500, false, gc)
|
||||
@ -735,29 +727,21 @@ func (app *appContext) ExtendExpiry(gc *gin.Context) {
|
||||
func (app *appContext) Announce(gc *gin.Context) {
|
||||
var req announcementDTO
|
||||
gc.BindJSON(&req)
|
||||
if !emailEnabled {
|
||||
if !(emailEnabled || app.config.Section("telegram").Key("enabled").MustBool(false)) {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
addresses := []string{}
|
||||
for _, userID := range req.Users {
|
||||
addr, ok := app.storage.emails[userID]
|
||||
if !ok || addr == "" {
|
||||
continue
|
||||
}
|
||||
addresses = append(addresses, addr.(string))
|
||||
}
|
||||
msg, err := app.email.constructTemplate(req.Subject, req.Message, app)
|
||||
if err != nil {
|
||||
app.err.Printf("Failed to construct announcement emails: %v", err)
|
||||
app.err.Printf("Failed to construct announcement messages: %v", err)
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
} else if err := app.email.send(msg, addresses...); err != nil {
|
||||
app.err.Printf("Failed to send announcement emails: %v", err)
|
||||
} else if err := app.sendByID(msg, req.Users...); err != nil {
|
||||
app.err.Printf("Failed to send announcement messages: %v", err)
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
app.info.Printf("Sent announcement email to %d users", len(addresses))
|
||||
app.info.Println("Sent announcement messages")
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
|
27
email.go
27
email.go
@ -755,3 +755,30 @@ func (emailer *Emailer) constructUserExpired(app *appContext, noSub bool) (*Mess
|
||||
func (emailer *Emailer) send(email *Message, address ...string) error {
|
||||
return emailer.sender.Send(emailer.fromName, emailer.fromAddr, email, address...)
|
||||
}
|
||||
|
||||
func (app *appContext) sendByID(email *Message, ID ...string) error {
|
||||
tgEnabled := app.config.Section("telegram").Key("enabled").MustBool(false)
|
||||
for _, id := range ID {
|
||||
var err error
|
||||
if tgChat, ok := app.storage.telegram[id]; ok && tgChat.Contact && tgEnabled {
|
||||
err = app.telegram.Send(email, tgChat.ChatID)
|
||||
} else if address, ok := app.storage.emails[id]; ok {
|
||||
err = app.email.send(email, address.(string))
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *appContext) getAddressOrName(jfID string) string {
|
||||
tgEnabled := app.config.Section("telegram").Key("enabled").MustBool(false)
|
||||
if tgChat, ok := app.storage.telegram[jfID]; ok && tgChat.Contact && tgEnabled {
|
||||
return "@" + tgChat.Username
|
||||
}
|
||||
if addr, ok := app.storage.emails[jfID]; ok {
|
||||
return addr.(string)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
window.URLBase = "{{ .urlBase }}";
|
||||
window.notificationsEnabled = {{ .notifications }};
|
||||
window.emailEnabled = {{ .email_enabled }};
|
||||
window.telegramEnabled = {{ .telegram_enabled }};
|
||||
window.ombiEnabled = {{ .ombiEnabled }};
|
||||
window.usernameEnabled = {{ .username }};
|
||||
window.langFile = JSON.parse({{ .language }});
|
||||
|
19
pwreset.go
19
pwreset.go
@ -69,27 +69,24 @@ func pwrMonitor(app *appContext, watcher *fsnotify.Watcher) {
|
||||
return
|
||||
}
|
||||
app.storage.loadEmails()
|
||||
var address string
|
||||
uid := user.ID
|
||||
if uid == "" {
|
||||
app.err.Printf("Couldn't get user ID for user \"%s\"", pwr.Username)
|
||||
return
|
||||
}
|
||||
addr, ok := app.storage.emails[uid]
|
||||
if !ok || addr == nil {
|
||||
app.err.Printf("Couldn't find email for user \"%s\". Make sure it's set", pwr.Username)
|
||||
return
|
||||
}
|
||||
address = addr.(string)
|
||||
name := app.getAddressOrName(uid)
|
||||
if name != "" {
|
||||
msg, err := app.email.constructReset(pwr, app, false)
|
||||
|
||||
if err != nil {
|
||||
app.err.Printf("Failed to construct password reset email for %s", pwr.Username)
|
||||
app.err.Printf("Failed to construct password reset message for %s", pwr.Username)
|
||||
app.debug.Printf("%s: Error: %s", pwr.Username, err)
|
||||
} else if err := app.email.send(msg, address); err != nil {
|
||||
app.err.Printf("Failed to send password reset email to \"%s\"", address)
|
||||
} else if err := app.sendByID(msg, uid); err != nil {
|
||||
app.err.Printf("Failed to send password reset message to \"%s\"", name)
|
||||
app.debug.Printf("%s: Error: %s", pwr.Username, err)
|
||||
} else {
|
||||
app.info.Printf("Sent password reset email to \"%s\"", address)
|
||||
app.info.Printf("Sent password reset message to \"%s\"", name)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
app.err.Printf("Password reset for user \"%s\" has already expired (%s). Check your time settings.", pwr.Username, pwr.Expiry)
|
||||
|
15
telegram.go
15
telegram.go
@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -194,15 +193,11 @@ func (t *TelegramDaemon) QuoteReply(upd *tg.Update, content string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Send adds compatibility with EmailClient, fromName/fromAddr are discarded, message.Text is used, addresses are Chat IDs as strings.
|
||||
func (t *TelegramDaemon) Send(fromName, fromAddr string, message *Message, address ...string) error {
|
||||
for _, addr := range address {
|
||||
ChatID, err := strconv.ParseInt(addr, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg := tg.NewMessage(ChatID, message.Text)
|
||||
_, err = t.bot.Send(msg)
|
||||
// Send will send a telegram message to a list of chat IDs. message.text is used.
|
||||
func (t *TelegramDaemon) Send(message *Message, ID ...int64) error {
|
||||
for _, id := range ID {
|
||||
msg := tg.NewMessage(id, message.Text)
|
||||
_, err := t.bot.Send(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ interface formWindow extends Window {
|
||||
code: string;
|
||||
messages: { [key: string]: string };
|
||||
confirmation: boolean;
|
||||
telegramEnabled: boolean;
|
||||
telegramRequired: boolean;
|
||||
telegramPIN: string;
|
||||
userExpiryEnabled: boolean;
|
||||
|
@ -334,7 +334,7 @@ export class accountsList {
|
||||
this._selectAll.checked = false;
|
||||
this._modifySettings.classList.add("unfocused");
|
||||
this._deleteUser.classList.add("unfocused");
|
||||
if (window.emailEnabled) {
|
||||
if (window.emailEnabled || window.telegramEnabled) {
|
||||
this._announceButton.classList.add("unfocused");
|
||||
}
|
||||
this._extendExpiry.classList.add("unfocused");
|
||||
@ -356,7 +356,7 @@ export class accountsList {
|
||||
this._modifySettings.classList.remove("unfocused");
|
||||
this._deleteUser.classList.remove("unfocused");
|
||||
this._deleteUser.textContent = window.lang.quantity("deleteUser", list.length);
|
||||
if (window.emailEnabled) {
|
||||
if (window.emailEnabled || window.telegramEnabled) {
|
||||
this._announceButton.classList.remove("unfocused");
|
||||
}
|
||||
let anyNonExpiries = list.length == 0 ? true : false;
|
||||
|
@ -18,6 +18,7 @@ declare interface Window {
|
||||
jfUsers: Array<Object>;
|
||||
notificationsEnabled: boolean;
|
||||
emailEnabled: boolean;
|
||||
telegramEnabled: boolean;
|
||||
ombiEnabled: boolean;
|
||||
usernameEnabled: boolean;
|
||||
token: string;
|
||||
|
@ -71,9 +71,10 @@ func (app *appContext) checkUsers() {
|
||||
mode = "delete"
|
||||
termPlural = "Deleting"
|
||||
}
|
||||
email := false
|
||||
if emailEnabled && app.config.Section("user_expiry").Key("send_email").MustBool(true) {
|
||||
email = true
|
||||
contact := false
|
||||
if (emailEnabled && app.config.Section("user_expiry").Key("send_email").MustBool(true)) ||
|
||||
app.config.Section("telegram").Key("enabled").MustBool(false) {
|
||||
contact = true
|
||||
}
|
||||
// Use a map to speed up checking for deleted users later
|
||||
userExists := map[string]bool{}
|
||||
@ -114,18 +115,18 @@ func (app *appContext) checkUsers() {
|
||||
}
|
||||
delete(app.storage.users, id)
|
||||
app.jf.CacheExpiry = time.Now()
|
||||
if email {
|
||||
address, ok := app.storage.emails[id]
|
||||
if contact {
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
name := app.getAddressOrName(user.ID)
|
||||
msg, err := app.email.constructUserExpired(app, false)
|
||||
if err != nil {
|
||||
app.err.Printf("Failed to construct expiry email for \"%s\": %s", user.Name, err)
|
||||
} else if err := app.email.send(msg, address.(string)); err != nil {
|
||||
app.err.Printf("Failed to send expiry email to \"%s\": %s", user.Name, err)
|
||||
app.err.Printf("Failed to construct expiry message for \"%s\": %s", user.Name, err)
|
||||
} else if err := app.sendByID(msg, user.ID); err != nil {
|
||||
app.err.Printf("Failed to send expiry message to \"%s\": %s", name, err)
|
||||
} else {
|
||||
app.info.Printf("Sent expiry notification to \"%s\"", address.(string))
|
||||
app.info.Printf("Sent expiry notification to \"%s\"", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
views.go
1
views.go
@ -120,6 +120,7 @@ func (app *appContext) AdminPage(gc *gin.Context) {
|
||||
"cssClass": app.cssClass,
|
||||
"contactMessage": "",
|
||||
"email_enabled": emailEnabled,
|
||||
"telegram_enabled": app.config.Section("telegram").Key("enabled").MustBool(false),
|
||||
"notifications": notificationsEnabled,
|
||||
"version": version,
|
||||
"commit": commit,
|
||||
|
Loading…
Reference in New Issue
Block a user