mirror of
https://github.com/usememos/memos.git
synced 2025-03-19 12:10:08 +01:00
fix: wrong order of the timeline in the resource page & add webhook when create memos using Telegram bot (#2886)
* fix: wrong order in resource page timeline * feat: add webhook when create memos using Telegram bot * rename variables and fix typos for static checks
This commit is contained in:
parent
e78311b3af
commit
7cd3fcbc61
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
"unicode/utf16"
|
||||
|
||||
"github.com/lithammer/shortuuid/v4"
|
||||
@ -13,7 +14,9 @@ import (
|
||||
|
||||
apiv1 "github.com/usememos/memos/api/v1"
|
||||
"github.com/usememos/memos/plugin/telegram"
|
||||
"github.com/usememos/memos/plugin/webhook"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/server/service/metric"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
@ -109,6 +112,9 @@ func (t *TelegramHandler) MessageHandle(ctx context.Context, bot *telegram.Bot,
|
||||
|
||||
keyboard := generateKeyboardForMemoID(memoMessage.ID)
|
||||
_, err = bot.EditMessage(ctx, message.Chat.ID, reply.MessageID, fmt.Sprintf("Saved as %s Memo %d", memoMessage.Visibility, memoMessage.ID), keyboard)
|
||||
|
||||
_ = t.dispatchMemoRelatedWebhook(ctx, *memoMessage, "memos.memo.created")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -135,7 +141,15 @@ func (t *TelegramHandler) CallbackQueryHandle(ctx context.Context, bot *telegram
|
||||
return bot.AnswerCallbackQuery(ctx, callbackQuery.ID, fmt.Sprintf("Failed to EditMessage %s", err))
|
||||
}
|
||||
|
||||
return bot.AnswerCallbackQuery(ctx, callbackQuery.ID, fmt.Sprintf("Success changing Memo %d to %s", memoID, visibility))
|
||||
err = bot.AnswerCallbackQuery(ctx, callbackQuery.ID, fmt.Sprintf("Success changing Memo %d to %s", memoID, visibility))
|
||||
|
||||
memo, webhookErr := t.store.GetMemo(ctx, &store.FindMemo{
|
||||
ID: &memoID,
|
||||
})
|
||||
if webhookErr == nil {
|
||||
_ = t.dispatchMemoRelatedWebhook(ctx, *memo, "memos.memo.updated")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func generateKeyboardForMemoID(id int32) [][]telegram.InlineKeyboardButton {
|
||||
@ -204,3 +218,79 @@ func convertToMarkdown(text string, messageEntities []telegram.MessageEntity) st
|
||||
|
||||
return string(output)
|
||||
}
|
||||
|
||||
func (t *TelegramHandler) dispatchMemoRelatedWebhook(ctx context.Context, memo store.Memo, activityType string) error {
|
||||
webhooks, err := t.store.ListWebhooks(ctx, &store.FindWebhook{
|
||||
CreatorID: &memo.CreatorID,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metric.Enqueue("webhook dispatch")
|
||||
for _, hook := range webhooks {
|
||||
payload := t.convertMemoToWebhookPayload(ctx, memo)
|
||||
payload.ActivityType = activityType
|
||||
payload.URL = hook.Url
|
||||
err := webhook.Post(*payload)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to post webhook")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TelegramHandler) convertMemoToWebhookPayload(ctx context.Context, memo store.Memo) (payload *webhook.WebhookPayload) {
|
||||
payload = &webhook.WebhookPayload{
|
||||
CreatorID: memo.CreatorID,
|
||||
CreatedTs: time.Now().Unix(),
|
||||
Memo: &webhook.Memo{
|
||||
ID: memo.ID,
|
||||
CreatorID: memo.CreatorID,
|
||||
CreatedTs: memo.CreatedTs,
|
||||
UpdatedTs: memo.UpdatedTs,
|
||||
Content: memo.Content,
|
||||
Visibility: memo.Visibility.String(),
|
||||
Pinned: memo.Pinned,
|
||||
ResourceList: make([]*webhook.Resource, 0),
|
||||
RelationList: make([]*webhook.MemoRelation, 0),
|
||||
},
|
||||
}
|
||||
|
||||
resourceList, err := t.store.ListResources(ctx, &store.FindResource{
|
||||
MemoID: &memo.ID,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return payload
|
||||
}
|
||||
for _, resource := range resourceList {
|
||||
payload.Memo.ResourceList = append(payload.Memo.ResourceList, &webhook.Resource{
|
||||
ID: resource.ID,
|
||||
CreatorID: resource.CreatorID,
|
||||
CreatedTs: resource.CreatedTs,
|
||||
UpdatedTs: resource.UpdatedTs,
|
||||
Filename: resource.Filename,
|
||||
Type: resource.Type,
|
||||
Size: resource.Size,
|
||||
InternalPath: resource.InternalPath,
|
||||
ExternalLink: resource.ExternalLink,
|
||||
})
|
||||
}
|
||||
|
||||
relationList, err := t.store.ListMemoRelations(ctx, &store.FindMemoRelation{
|
||||
MemoID: &memo.ID,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return payload
|
||||
}
|
||||
|
||||
for _, relation := range relationList {
|
||||
payload.Memo.RelationList = append(payload.Memo.RelationList, &webhook.MemoRelation{
|
||||
MemoID: relation.MemoID,
|
||||
RelatedMemoID: relation.RelatedMemoID,
|
||||
Type: string(relation.Type),
|
||||
})
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
@ -15,8 +15,15 @@ import { Resource } from "@/types/proto/api/v2/resource_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
function groupResourcesByDate(resources: Resource[]) {
|
||||
const tmp_resources: Resource[] = resources.slice();
|
||||
tmp_resources.sort((a: Resource, b: Resource) => {
|
||||
const a_date = new Date(a.createTime as any);
|
||||
const b_date = new Date(b.createTime as any);
|
||||
return b_date.getTime() - a_date.getTime();
|
||||
});
|
||||
|
||||
const grouped = new Map<number, Resource[]>();
|
||||
resources.forEach((item) => {
|
||||
tmp_resources.forEach((item) => {
|
||||
const date = new Date(item.createTime as any);
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
@ -41,15 +48,15 @@ const Resources = () => {
|
||||
});
|
||||
const memoStore = useMemoStore();
|
||||
const [resources, setResources] = useState<Resource[]>([]);
|
||||
const filteredResources = resources.filter((resource) => includes(resource.filename, state.searchQuery));
|
||||
const groupedResources = groupResourcesByDate(filteredResources.filter((resoure) => resoure.memoId));
|
||||
const unusedResources = filteredResources.filter((resoure) => !resoure.memoId);
|
||||
const filteredResources = resources.filter((resource: any) => includes(resource.filename, state.searchQuery));
|
||||
const groupedResources = groupResourcesByDate(filteredResources.filter((resource: any) => resource.memoId));
|
||||
const unusedResources = filteredResources.filter((resource: any) => !resource.memoId);
|
||||
|
||||
useEffect(() => {
|
||||
resourceServiceClient.listResources({}).then(({ resources }) => {
|
||||
setResources(resources);
|
||||
loadingState.setFinish();
|
||||
Promise.all(resources.map((resource) => (resource.memoId ? memoStore.getOrFetchMemoById(resource.memoId) : null)));
|
||||
Promise.all(resources.map((resource: any) => (resource.memoId ? memoStore.getOrFetchMemoById(resource.memoId) : null)));
|
||||
});
|
||||
}, []);
|
||||
|
||||
@ -63,7 +70,7 @@ const Resources = () => {
|
||||
for (const resource of unusedResources) {
|
||||
await resourceServiceClient.deleteResource({ id: resource.id });
|
||||
}
|
||||
setResources(resources.filter((resoure) => resoure.memoId));
|
||||
setResources(resources.filter((resource) => resource.memoId));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user