ikemoji 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/index.js +95 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# ikemoji
|
|
2
|
+
|
|
3
|
+
Telegram Bot API 9.4 – Custom Emoji Helper
|
|
4
|
+
|
|
5
|
+
- UTF-16 correct
|
|
6
|
+
- ZWJ / skin tone safe
|
|
7
|
+
- Length = 1 (Telegram requirement)
|
|
8
|
+
- Handles multiple consecutive emojis and variation selectors
|
|
9
|
+
- Telegraf compatible
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install ikemoji
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
const { emo, emoEnt, findEmo, checkEnt, mergeEntities } = require('ikemoji');
|
|
21
|
+
|
|
22
|
+
const emojiMap = {
|
|
23
|
+
"😀": "5444871234567890123",
|
|
24
|
+
"🔥": "5444879876543210123"
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Build text + entities
|
|
28
|
+
const { text, entities } = emo("Hello 😀🔥", emojiMap);
|
|
29
|
+
console.log(text); // "Hello 😀🔥"
|
|
30
|
+
console.log(entities); // [{ type: 'custom_emoji', offset: 6, length: 1, custom_emoji_id: "..." }, ...]
|
|
31
|
+
|
|
32
|
+
// Extract entities only
|
|
33
|
+
const onlyEntities = emoEnt("Hello 😀🔥", emojiMap);
|
|
34
|
+
console.log(onlyEntities);
|
|
35
|
+
|
|
36
|
+
// Find all unique emojis
|
|
37
|
+
const unique = findEmo("Hello 😀🔥");
|
|
38
|
+
console.log(unique); // ["😀","🔥"]
|
|
39
|
+
|
|
40
|
+
// Validate entities
|
|
41
|
+
const { valid, errors } = checkEnt(entities);
|
|
42
|
+
console.log(valid, errors);
|
|
43
|
+
|
|
44
|
+
// Merge with other entities
|
|
45
|
+
const allEntities = mergeEntities(entities, [{ type: 'bold', offset: 0, length: 5 }]);
|
|
46
|
+
console.log(allEntities);
|
package/index.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telegram Bot API 9.4 – Custom Emoji Helper
|
|
3
|
+
* Author: ikjava
|
|
4
|
+
* ✔ UTF-16 correct
|
|
5
|
+
* ✔ ZWJ / skin tone safe
|
|
6
|
+
* ✔ length = 1
|
|
7
|
+
* ✔ Handles multiple consecutive emojis and variation selectors
|
|
8
|
+
* ✔ Telegraf compatible
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
|
|
12
|
+
|
|
13
|
+
function emo(text, emojiMap, options = {}) {
|
|
14
|
+
const { stripOriginal = false, skipUnmapped = true } = options;
|
|
15
|
+
const entities = [];
|
|
16
|
+
let out = '';
|
|
17
|
+
let offset = 0;
|
|
18
|
+
|
|
19
|
+
for (const { segment } of segmenter.segment(text)) {
|
|
20
|
+
const id = emojiMap[segment];
|
|
21
|
+
|
|
22
|
+
if (id) {
|
|
23
|
+
entities.push({ type: 'custom_emoji', offset, length: 1, custom_emoji_id: id });
|
|
24
|
+
if (!stripOriginal) {
|
|
25
|
+
out += segment;
|
|
26
|
+
offset += segment.length;
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
if (!skipUnmapped || isEmo(segment) === false) {
|
|
30
|
+
out += segment;
|
|
31
|
+
offset += segment.length;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return { text: out, entities };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function emoEnt(text, emojiMap) {
|
|
40
|
+
const entities = [];
|
|
41
|
+
let offset = 0;
|
|
42
|
+
|
|
43
|
+
for (const { segment } of segmenter.segment(text)) {
|
|
44
|
+
if (emojiMap[segment]) {
|
|
45
|
+
entities.push({ type: 'custom_emoji', offset, length: 1, custom_emoji_id: emojiMap[segment] });
|
|
46
|
+
}
|
|
47
|
+
offset += segment.length;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return entities;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function findEmo(text) {
|
|
54
|
+
const set = new Set();
|
|
55
|
+
|
|
56
|
+
for (const { segment } of segmenter.segment(text)) {
|
|
57
|
+
if (isEmo(segment)) set.add(segment);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return [...set];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function checkEnt(entities) {
|
|
64
|
+
const errors = [];
|
|
65
|
+
|
|
66
|
+
if (entities.length > 100) errors.push(`Too many entities (${entities.length})`);
|
|
67
|
+
|
|
68
|
+
entities.forEach((e, i) => {
|
|
69
|
+
if (e.type !== 'custom_emoji') errors.push(`Entity ${i}: invalid type`);
|
|
70
|
+
if (!e.custom_emoji_id) errors.push(`Entity ${i}: missing custom_emoji_id`);
|
|
71
|
+
if (e.length !== 1) errors.push(`Entity ${i}: length must be 1`);
|
|
72
|
+
if (typeof e.offset !== 'number' || e.offset < 0) errors.push(`Entity ${i}: invalid offset`);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return { valid: errors.length === 0, errors };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function isEmo(str) {
|
|
79
|
+
return /\p{Extended_Pictographic}/u.test(str);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function mergeEntities(baseEntities, newEntities) {
|
|
83
|
+
const all = [...baseEntities, ...newEntities];
|
|
84
|
+
all.sort((a, b) => a.offset - b.offset);
|
|
85
|
+
return all;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
emo,
|
|
90
|
+
emoEnt,
|
|
91
|
+
findEmo,
|
|
92
|
+
checkEnt,
|
|
93
|
+
isEmo,
|
|
94
|
+
mergeEntities
|
|
95
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ikemoji",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Telegram Bot API 9.4 custom emoji helper - UTF-16 correct, ZWJ/skin tone safe, Telegraf compatible",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "node test.js"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"telegram",
|
|
11
|
+
"bot",
|
|
12
|
+
"custom",
|
|
13
|
+
"emoji",
|
|
14
|
+
"telegram-bot-api",
|
|
15
|
+
"telegraf",
|
|
16
|
+
"caption",
|
|
17
|
+
"9.4"
|
|
18
|
+
],
|
|
19
|
+
"author": "Saul ikjava",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=16"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {},
|
|
25
|
+
"devDependencies": {}
|
|
26
|
+
}
|