mirror of
https://github.com/usememos/memos.git
synced 2025-02-16 03:12:13 +01:00
feat: notify by telegram while new memo create by HTTP (#2215)
* Inject telegram bot into API service * Add support for send telegram message * Send notification by telegram while new memo post
This commit is contained in:
parent
36209eaef1
commit
626ff5e3a7
@ -11,8 +11,10 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/usememos/memos/api/auth"
|
"github.com/usememos/memos/api/auth"
|
||||||
|
"github.com/usememos/memos/common/log"
|
||||||
"github.com/usememos/memos/common/util"
|
"github.com/usememos/memos/common/util"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Visibility is the type of a visibility.
|
// Visibility is the type of a visibility.
|
||||||
@ -351,6 +353,38 @@ func (s *APIV1Service) CreateMemo(c echo.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send notification by telegram bot if memo is not Private
|
||||||
|
if memoResponse.Visibility != Private {
|
||||||
|
// fetch all telegram UserID
|
||||||
|
userSettings, err := s.Store.ListUserSettings(ctx, &store.FindUserSetting{Key: UserSettingTelegramUserIDKey.String()})
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to ListUserSettings").SetInternal(err)
|
||||||
|
}
|
||||||
|
for _, userSetting := range userSettings {
|
||||||
|
// parse telegram UserID setting value into a int64
|
||||||
|
var tgUserIDStr string
|
||||||
|
err := json.Unmarshal([]byte(userSetting.Value), &tgUserIDStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to parse Telegram UserID", zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
tgUserID, err := strconv.ParseInt(tgUserIDStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to parse Telegram UserID", zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// send notification to telegram
|
||||||
|
content := memoResponse.CreatorName + " Says:\n\n" + memoResponse.Content
|
||||||
|
_, err = s.telegramBot.SendMessage(ctx, tgUserID, content)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Failed to send Telegram notification", zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return c.JSON(http.StatusOK, memoResponse)
|
return c.JSON(http.StatusOK, memoResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
api/v1/v1.go
17
api/v1/v1.go
@ -2,14 +2,16 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/usememos/memos/plugin/telegram"
|
||||||
"github.com/usememos/memos/server/profile"
|
"github.com/usememos/memos/server/profile"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type APIV1Service struct {
|
type APIV1Service struct {
|
||||||
Secret string
|
Secret string
|
||||||
Profile *profile.Profile
|
Profile *profile.Profile
|
||||||
Store *store.Store
|
Store *store.Store
|
||||||
|
telegramBot *telegram.Bot
|
||||||
}
|
}
|
||||||
|
|
||||||
// @title memos API
|
// @title memos API
|
||||||
@ -31,11 +33,12 @@ type APIV1Service struct {
|
|||||||
// @in query
|
// @in query
|
||||||
// @name openId
|
// @name openId
|
||||||
// @description Insert your Open ID API Key here.
|
// @description Insert your Open ID API Key here.
|
||||||
func NewAPIV1Service(secret string, profile *profile.Profile, store *store.Store) *APIV1Service {
|
func NewAPIV1Service(secret string, profile *profile.Profile, store *store.Store, telegramBot *telegram.Bot) *APIV1Service {
|
||||||
return &APIV1Service{
|
return &APIV1Service{
|
||||||
Secret: secret,
|
Secret: secret,
|
||||||
Profile: profile,
|
Profile: profile,
|
||||||
Store: store,
|
Store: store,
|
||||||
|
telegramBot: telegramBot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,9 +9,12 @@ import (
|
|||||||
// SendReplyMessage make a sendMessage api request.
|
// SendReplyMessage make a sendMessage api request.
|
||||||
func (b *Bot) SendReplyMessage(ctx context.Context, chatID, replyID int64, text string) (*Message, error) {
|
func (b *Bot) SendReplyMessage(ctx context.Context, chatID, replyID int64, text string) (*Message, error) {
|
||||||
formData := url.Values{
|
formData := url.Values{
|
||||||
"reply_to_message_id": {strconv.FormatInt(replyID, 10)},
|
"chat_id": {strconv.FormatInt(chatID, 10)},
|
||||||
"chat_id": {strconv.FormatInt(chatID, 10)},
|
"text": {text},
|
||||||
"text": {text},
|
}
|
||||||
|
|
||||||
|
if replyID > 0 {
|
||||||
|
formData.Set("reply_to_message_id", strconv.FormatInt(replyID, 10))
|
||||||
}
|
}
|
||||||
|
|
||||||
var result Message
|
var result Message
|
||||||
@ -22,3 +25,8 @@ func (b *Bot) SendReplyMessage(ctx context.Context, chatID, replyID int64, text
|
|||||||
|
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SendMessage make a sendMessage api request.
|
||||||
|
func (b *Bot) SendMessage(ctx context.Context, chatID int64, text string) (*Message, error) {
|
||||||
|
return b.SendReplyMessage(ctx, chatID, 0, text)
|
||||||
|
}
|
||||||
|
@ -46,6 +46,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
|||||||
e.HideBanner = true
|
e.HideBanner = true
|
||||||
e.HidePort = true
|
e.HidePort = true
|
||||||
|
|
||||||
|
telegramBot := telegram.NewBotWithHandler(newTelegramHandler(store))
|
||||||
s := &Server{
|
s := &Server{
|
||||||
e: e,
|
e: e,
|
||||||
Store: store,
|
Store: store,
|
||||||
@ -53,7 +54,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
|||||||
|
|
||||||
// Asynchronous runners.
|
// Asynchronous runners.
|
||||||
backupRunner: service.NewBackupRunner(store),
|
backupRunner: service.NewBackupRunner(store),
|
||||||
telegramBot: telegram.NewBotWithHandler(newTelegramHandler(store)),
|
telegramBot: telegramBot,
|
||||||
}
|
}
|
||||||
|
|
||||||
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||||
@ -103,7 +104,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
|||||||
s.Secret = secret
|
s.Secret = secret
|
||||||
|
|
||||||
rootGroup := e.Group("")
|
rootGroup := e.Group("")
|
||||||
apiV1Service := apiv1.NewAPIV1Service(s.Secret, profile, store)
|
apiV1Service := apiv1.NewAPIV1Service(s.Secret, profile, store, telegramBot)
|
||||||
apiV1Service.Register(rootGroup)
|
apiV1Service.Register(rootGroup)
|
||||||
|
|
||||||
s.apiV2Service = apiv2.NewAPIV2Service(s.Secret, profile, store, s.Profile.Port+1)
|
s.apiV2Service = apiv2.NewAPIV2Service(s.Secret, profile, store, s.Profile.Port+1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user