Skip to content

Commit

Permalink
feat: add path templates
Browse files Browse the repository at this point in the history
feat: add path templates
  • Loading branch information
soberhacker authored Sep 16, 2023
1 parent 2292474 commit 04242e7
Show file tree
Hide file tree
Showing 16 changed files with 890 additions and 340 deletions.
169 changes: 86 additions & 83 deletions docs/Template Variables List.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,72 @@
#### Note Content Template
### Message Filter Variables

```ts
{{all}} - all messages
{{user=VALUE}} - messages from user with username, full name or id equal VALUE
{{chat=VALUE}} - messages in bot | group | channel with name or id equal VALUE
{{topic=VALUE}} - messages in topic with name VALUE
{{forwardFrom=VALUE}} - messages forwarded from chat or user with name VALUE
{{content~VALUE}} - messages contain text VALUE
```

#### Filter examples:

```js
// messages from group "My Notes" in topic "Memes" will be selected
{{chat=My Notes}}{{topic=Memes}}
// messages that simultaneously have hash tags #video and #movie will be selected
{{content~#video}}{{content~#movie}}
```

- AND is default operator between conditions
- If **Message Filter** is unspecified, filter by default will be equal {{all}}
<br><br>

### Generic Template Variables

###### Variables:
```ts
{{content}} - forwarded from + file|image + message text
{{content:text}} - only message text
{{content:XX}} - XX characters of the message text
{{content:[X-Y]}} - all lines from line number X to Y, inclusive
{{files}} - files | images ![]()
{{files:links}} - links to files | images []()
{{voiceTranscript}} - transcribing voice(video notes!) to text (same limits as for Telegram Premium subscribers)
{{chat}} - link to the chat (bot / group / channel)
{{chatId}} - id of the chat (bot / group / channel)
{{chat:name}} - name of the chat (bot / group / channel)
{{chat}} - link to the chat (bot | group | channel)
{{chatId}} - id of the chat (bot | group | channel)
{{chat:name}} - name of the chat (bot | group | channel)
{{topic}} - link to the topic (if the topic name displays incorrect, set the name manually using bot command "/topicName NAME")
{{topic:name}} - name of the topic
{{topicId}} - head message id representing the topic
{{messageId}} - message id
{{replyMessageId}} - reply message id
{{user}} - link to the user who sent the message
{{user:name}} - username who sent the message
{{user:fullName}} - full name who sent the message
{{userId}} - id of the user who sent the message
{{forwardFrom}} - link to the forwarded message or its creator (user / channel)
{{forwardFrom}} - link to the forwarded message or its creator (user | channel)
{{forwardFrom:name}} - name of forwarded message creator
{{messageDate:YYYYMMDD}} - date, when the message was sent
{{messageTime:HHmmss}} - time, when the message was sent
{{creationDate:YYYYMMDD}} - date, when the message was created
{{creationTime:HHmmss}} - time, when the message was created
{{hashtag:[X]}} - hashtag (without #) at number X in the message text
```

- All available formats for dates and time you can find in [Moment JS Docs](https://momentjs.com/docs/#/parsing/string-format/)
- **Generic variables** can be used in the following content and path templates
<br><br>

### Note Content Variables

```ts
{{content}} - forwarded from + file | image + message text
{{content:text}} - only message text
{{content:[X-Y]}} - all lines from line number X to Y, inclusive
{{files}} - files | images ![]()
{{files:links}} - links to files | images []()
{{voiceTranscript}} - transcribing voice (video notes!) to text (same limits as for Telegram Premium subscribers)
{{url1}} - first url from the message
{{url1:previewYYY}} - first url preview with YYY pixels height (default 250)
{{replace:TEXT=>WITH}} - replace or delete text in resulting note (\n - new line)
```

###### Template example:
#### Note content template example:

```
{{messageDate:YYYY}} {{content:[1]}}
Expand All @@ -44,87 +80,54 @@ Created: {{creationDate:YYYY-DD-MM}} {{creationTime:HH:mm:ss}}
{{replace:\n\n=>\n}}
```

- If Note Content Template is unspecified, template by default will be equal {{content}}
- All available formats for dates and time you can find in [Moment JS Docs](https://momentjs.com/docs/#/parsing/string-format/)

- If **Template file** is unspecified, template by default will be equal {{content}}
<br><br>

### Note Path Variables


#### ❌ Note Path Template (*not implemented*)

###### Variables:
```json
❌{{user:VALUE}} - only when user name equal VALUE use this path
❌{{userId:VALUE}} - only when user id equal VALUE use this path
❌{{chat:VALUE}} - only when chat name equal VALUE use this path
❌{{chatId:VALUE}} - only when chat id equal VALUE use this path
❌{{topic:VALUE}} - only when topic name equal VALUE use this path
❌{{forwardFrom:VALUE}} - only when message creator equal VALUE use this path
```ts
{{content:XX}} - XX characters of the message text (max 100 characters)
{{content:[X]}} - message line number X
{{messageTime:YYYYMMDDHHmmssSSS}} - use full time format for creating unique note names
```

###### ❌ Note Paths examples (*not implemented*):
#### Note paths examples:

```js
// All news are written in one folder, other messages - in file Telegram.md
myNotes/WorldNews/{{forwardFrom:Forbes}}.md
myNotes/WorldNews/{{forwardFrom:The Washington Post}}.md
myNotes/Telegram.md

// Important channels are written in separate folders, other messages - in root folder in separate notes
myNotes/{{chat:Recipes}}/{content:30}.md
myNotes/{{chat:Ideas}}/{{content:[1]}}.md
myNotes/{{chat:Work}}/{{forwardFrom}}_{{creationDate}}.md
myNotes/{{content:20}}_{{messageDate}}_{{messageTime}}.md

// Other examples
myNotes/inbox.md
myNotes/{{chat}}/{{forwardFrom}}/{{content}}.md
myNotes/{{chat:Surf Shop}}{{user:Me}}/Announcements.md
myNotes/daily/{{messageDate}}.md
myNotes/{{messageDate:YYYY}}/{{forwardFrom}}/{{content:[1]}}.md
myNotes/{{messageDate:YYYY}}/{{messageDate:MM}}/{{messageDate:DD}}/{{messageTime:HHmmssSSS}}.md
myNotes/{{creationDate:YYYY}}/{{creationDate:MM-DD}}.{{creationTime:HH:mm:ss(SSS)}}.md
// A separate note is created for each message, because note names are based on message text and time
Telegram/{{content:30}} - {{messageTime:YYYYMMDDHHmmssSSS}}.md
// All message are appended to the note with name "Telegram.md"
Telegram.md
// All messages from one day are added to a daily note
{{messageDate:YYYYMMDD}}.md
// For every chat will be created separate folder
myNotes/{{chat:name}}/{{forwardFrom:name}}/{{content:[1]}}.md
// Messages are grouped by year, month, day and time
myNotes/{{messageDate:YYYY/MM/DD}}/{{messageTime:HHmmssSSS}}.md
```

- **Note Content Template Variables** are also available here (except for {{file*}}, {{url1*}}, {{replace*}}, {{content}}, {{content:text}})
- Always define note names and finish paths with *".md"*
- If a note with such name exists then new data will be always appended to this notes




#### ❌ File Path Template (*not implemented*)

###### Variables:
```json
❌{{fileType}} - file type identified by Telegram (video, audio, voice, photo, document...)
❌{{fileExtension}} - file extension (mp3, ogg, docx, png...)
❌{{fileName}} - unique file name assigned by Telegram (without extension)
```

###### ❌ File Paths examples (*not implemented*):
```js
myFiles/{{fileType}}/{{fileName}}.{{fileExtension}}
myFiles/{{forwardFrom}}_{{fileName}}.{{fileExtension}}
myFiles/{{messageDate:YYYY}}/{{fileType}}.{{messageTime:HHmmss}}.{{fileName}}.{{fileExtension}}
⚠️ If a note path template is empty, then notes will not be created
⚠️ If a note with such name exists then new data will be always appended to this notes
```

- **Note Content Template Variables** are also available here (except for {{file*}}, {{url1*}}, {{replace*}}, {{content}}, {{content:text}})
- Always define file names and finish paths with *".{{fileExtension}}"*
- If a file with such name exists then new file will be created with auto-generated unique name




#### ⚠ Not Implemented Features ⚠

Integrating these new features might prove challenging and time-consuming, so your assistance would be much appreciated. You can help by:
- Donating to enhance my motivation
- Contributing to the development (branch "[develop](https://github.com/soberhacker/obsidian-telegram-sync/tree/develop)")
### File Path Variables

[![boosty](https://img.buymeacoffee.com/button-api/?text=boosty&emoji=💰&slug=soberhacker&button_colour=f17d1e&font_colour=000000&font_family=Bree&outline_colour=000000&coffee_colour=FFDD00)](https://boosty.to/soberhacker/donate)
```ts
{{file:type}} - file type identified by Telegram (video, audio, voice, photo, document)
{{file:extension}} - file extension (mp3, ogg, docx, png...)
{{file:name}} - file name assigned by Telegram (without extension)
```

[![Buy me a coffee](https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20coffee&emoji=%E2%98%95&slug=soberhacker&button_colour=5F7FFF&font_colour=ffffff&font_family=Cookie&outline_colour=000000&coffee_colour=FFFFFF)](https://www.buymeacoffee.com/soberhacker)
#### File paths examples:

[![Ko-fi Donation](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/soberhacker)
```js
Telegram/{{file:type}}s/{{file:name}} - {{messageTime:YYYYMMDDHHmmssSSS}}.{{file:extension}}
myFiles/{{forwardFrom:name}}_{{file:name}}_{{messageTime:YYYYMMDDHHmmssSSS}}.{{file:extension}}
myFiles/{{messageDate:YYYY/MM/DD}}/{{file:type}}.{{messageTime:HHmmssSSS}}.{{file:name}}.{{file:extension}}
```

[![PayPal](https://www.paypalobjects.com/webstatic/en_US/i/buttons/PP_logo_h_100x26.png)](https://www.paypal.com/donate/?hosted_button_id=VYSCUZX8MYGCU)
```json
⚠️ If a file path template is empty then files will not be saved
⚠️ If a file already exists, ` - {{messageTime:YYYYMMDDHHmmssSSS}}` will be added to its name
```
15 changes: 10 additions & 5 deletions release-notes.mjs
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import { compareVersions } from "compare-versions";

export const version = "1.10.0";
export const version = "2.0.0";
// TODO getting messages one by one instead of parallel processing
// TODO add Demo gif and screenshots to readme.md
// ## Demo
//![](https://raw.githubusercontent.com/vslinko/obsidian-outliner/main/demos/demo1.gif)<br>
export const showNewFeatures = true;
export let showBreakingChanges = false;
export let showBreakingChanges = true;

const newFeatures =
"This release introduces connection status indicator instead of notifications, along with 5 other important features.";
"This release introduces the long-awaited feature of Path Templates. " +
"This feature will help personalize your experience in many many ways, including:\n" +
" - customizing note and file names\n" +
" - appending data to any periodic notes (daily notes, etc)\n" +
" - distributing messages across different folders\n" +
"Many thanks to all contributors, especially to @ro_mashaaa, @fokinevgenij!";
export const breakingChanges =
"⚠️ <b><i>If you were connected as a user, due to API changes, the user has been disconnected and needs to be reconnected! Apologies</i></b> ⚠️";
"⚠️ <b><i>Due to breaking changes, it is better to check all plugin settings again! Apologies</i></b> ⚠️";

const telegramChannelLink = "<a href='https://t.me/obsidian_telegram_sync_insider'>channel</a>";
const telegramChannelIntroduction = `Find the complete list of new features on the plugin's ${telegramChannelLink}.`;
const telegramChannelIntroduction = `Subscribe to the plugin's ${telegramChannelLink} to not only silence these informational messages in your bot, but also to be the first to get all the latest updates and a complete list of new features.`;
const telegramChatLink = "<a href='https://t.me/ObsidianTelegramSync'>chat</a>";
const telegramChatIntroduction = `For discussions, please feel free to join the plugin's ${telegramChatLink}.`;
const donation =
Expand Down
58 changes: 54 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ import { clearCachedMessagesInterval } from "./telegram/user/convertors";
import { clearHandleMediaGroupInterval } from "./telegram/bot/message/handlers";
import ConnectionStatusIndicator, { checkConnectionMessage } from "./ConnectionStatusIndicator";
import { mainDeviceIdSettingName } from "./settings/BotSettingsModal";
import {
createDefaultMessageDistributionRule,
createDefaultMessageFilterCondition,
defaultFileNameTemplate,
defaultMessageFilterQuery,
defaultNoteNameTemplate,
defaultTelegramFolder,
} from "./settings/messageDistribution";

// TODO: add "connecting"
export type ConnectionStatus = "connected" | "disconnected";
Expand All @@ -29,7 +37,7 @@ export default class TelegramSyncPlugin extends Plugin {
// TODO: TelegramSyncBot extends TelegramBot
bot?: TelegramBot;
botUser?: TelegramBot.User;
listOfNotePaths: string[] = [];
createdFilePaths: string[] = [];
currentDeviceId = machineIdSync(true);
lastPollingErrors: string[] = [];
restartingIntervalId?: NodeJS.Timer;
Expand Down Expand Up @@ -170,20 +178,62 @@ export default class TelegramSyncPlugin extends Plugin {
}

async upgradeSettings() {
let needToSaveSettings = false;
if (this.settings.cacheCleanupAtStartup) {
localStorage.removeItem("GramJs:apiCache");
this.settings.cacheCleanupAtStartup = false;
await this.saveSettings();
needToSaveSettings = true;
}
// TODO in 2024: Remove allowedChatFromUsernames, because it is deprecated
if (this.settings.allowedChatFromUsernames.length != 0) {
this.settings.allowedChats = [...this.settings.allowedChatFromUsernames];
this.settings.allowedChatFromUsernames = [];
await this.saveSettings();
needToSaveSettings = true;
}

// TODO in 2024: Remove this block, because messageDistributionRules should be established by that time
if (this.settings.newNotesLocation || this.settings.newFilesLocation || this.settings.templateFileLocation) {
this.settings.messageDistributionRules = [];
this.settings.messageDistributionRules.push({
messageFilterQuery: defaultMessageFilterQuery,
messageFilterConditions: [createDefaultMessageFilterCondition()],
templateFilePath: this.settings.templateFileLocation,
notePathTemplate: `${this.settings.newNotesLocation || defaultTelegramFolder}/${
this.settings.appendAllToTelegramMd ? "Telegram.md" : defaultNoteNameTemplate
}`,
filePathTemplate: this.settings.needToSaveFiles
? `${this.settings.newFilesLocation || defaultTelegramFolder}/${defaultFileNameTemplate}`
: "",
});
this.settings.newNotesLocation = "";
this.settings.newFilesLocation = "";
this.settings.templateFileLocation = "";
needToSaveSettings = true;
}

if (this.settings.messageDistributionRules.length == 0) {
this.settings.messageDistributionRules.push(createDefaultMessageDistributionRule());
needToSaveSettings = true;
} else {
// fixing incorrectly saved rules
this.settings.messageDistributionRules.forEach((rule) => {
if (!rule.messageFilterQuery || !rule.messageFilterConditions) {
rule.messageFilterQuery = defaultMessageFilterQuery;
rule.messageFilterConditions = [createDefaultMessageFilterCondition()];
needToSaveSettings = true;
}
if (!rule.filePathTemplate && !rule.notePathTemplate && !rule.templateFilePath) {
rule.notePathTemplate = `${defaultTelegramFolder}/${defaultNoteNameTemplate}`;
rule.filePathTemplate = `${defaultTelegramFolder}/${defaultFileNameTemplate}`;
needToSaveSettings = true;
}
});
}

needToSaveSettings && this.saveSettings();
}

async getBotUser(msg: TelegramBot.Message): Promise<TelegramBot.User> {
async getBotUser(): Promise<TelegramBot.User> {
this.botUser = this.botUser || (await this.bot?.getMe());
if (!this.botUser) throw new Error("Can't get access to bot info. Restart the Telegram Sync plugin");
return this.botUser;
Expand Down
Loading

0 comments on commit 04242e7

Please sign in to comment.