Import IKAR messenger client and server
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import { chat, contact, runtime, ui } from 'komet:api';
|
||||
|
||||
function date(value) {
|
||||
if (!Number.isInteger(value) || value <= 0) return '—';
|
||||
return new Date(value).toLocaleString();
|
||||
}
|
||||
|
||||
export async function info() {
|
||||
if (!(await runtime.isOnline())) {
|
||||
await ui.notify('Нет соединения');
|
||||
return;
|
||||
}
|
||||
const id = await chat.sendText('сбор данных...');
|
||||
const peer = await contact.getPeer();
|
||||
if (!peer) {
|
||||
await chat.editText(id, 'Команда доступна только в диалоге');
|
||||
return;
|
||||
}
|
||||
const summary = [
|
||||
`Никнейм: ${peer.displayName || '—'}`,
|
||||
`Дата регистрации: ${date(peer.registrationTime)}`,
|
||||
`Дата последнего изменения профиля: ${date(peer.updateTime)}`,
|
||||
`id: ${peer.id}`,
|
||||
`Регион: ${peer.country || '—'}`,
|
||||
`Флаги: ${peer.options.length ? peer.options.join(', ') : '—'}`,
|
||||
'ip: not fetched'
|
||||
].join('\n');
|
||||
await chat.editText(id, summary);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "pw.qlyra.info",
|
||||
"name": "ИКАР Info",
|
||||
"version": "1.0.0",
|
||||
"apiVersion": 1,
|
||||
"description": "Сводка данных о собеседнике",
|
||||
"author": "ИКАР",
|
||||
"main": "main.js",
|
||||
"permissions": ["chat.write", "chat.edit", "ui.notify", "contact.read"],
|
||||
"commands": [
|
||||
{"name": "/info", "description": "сводка данных о человеке", "handler": "info"}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { chat, network, ui } from 'komet:api';
|
||||
|
||||
export async function nekogirl() {
|
||||
const response = await network.fetch('https://api.nekosapi.com/v4/images/random?rating=safe', {
|
||||
headers: { Accept: 'application/json' }
|
||||
});
|
||||
if (response.status !== 200) {
|
||||
await ui.notify(`Nekogirl вернул HTTP ${response.status}`);
|
||||
return;
|
||||
}
|
||||
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(response.body);
|
||||
} catch (_) {
|
||||
await ui.notify('Nekogirl вернул некорректный ответ');
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof data[0].url !== 'string' || !data[0].url.startsWith('https://')) {
|
||||
await ui.notify('Nekogirl не вернул ссылку на изображение');
|
||||
return;
|
||||
}
|
||||
|
||||
const filename = data[0].url.split('/').pop() || 'nekogirl.jpg';
|
||||
|
||||
const source = data[0].url;
|
||||
await chat.sendPhoto({
|
||||
url: data[0].url,
|
||||
filename,
|
||||
caption: `Случайная кошкодевочкa`
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"schemaVersion":1,"id":"pw.qlyra.nekos","name":"ИКАР Nekos","version":"1.0.0","apiVersion":1,"description":"Случайные картинки кошкодевочек через nekosapi.com","author":"nyakokitsu","main":"main.js","permissions":["network","chat.photo","chat.write","ui.notify"],"commands":[{"name":"/nekogirl","description":"отправить случайную картинку кошкодевочки","handler":"nekogirl"}]}
|
||||
@@ -0,0 +1,63 @@
|
||||
import { chat, network, ui } from 'komet:api';
|
||||
|
||||
function value(source, key, fallback = '—') {
|
||||
const result = source?.[key];
|
||||
return result === undefined || result === null || result === '' ? fallback : String(result);
|
||||
}
|
||||
|
||||
function description(source) {
|
||||
return source?.weatherDesc?.[0]?.value || '—';
|
||||
}
|
||||
|
||||
function dayLabel(date, index) {
|
||||
if (index === 0) return 'Сегодня';
|
||||
if (index === 1) return 'Завтра';
|
||||
return date || `День ${index + 1}`;
|
||||
}
|
||||
|
||||
export async function weather(context) {
|
||||
const city = context.arguments.city.trim();
|
||||
const url = `https://wttr.in/${encodeURIComponent(city)}?format=j1&lang=ru`;
|
||||
const response = await network.fetch(url, {
|
||||
headers: { Accept: 'application/json' }
|
||||
});
|
||||
if (response.status !== 200) {
|
||||
await ui.notify(`wttr.in вернул HTTP ${response.status}`);
|
||||
return;
|
||||
}
|
||||
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(response.body);
|
||||
} catch (_) {
|
||||
await ui.notify('wttr.in вернул некорректный ответ');
|
||||
return;
|
||||
}
|
||||
|
||||
const current = data.current_condition?.[0];
|
||||
const area = data.nearest_area?.[0];
|
||||
if (!current) {
|
||||
await ui.notify('Погода для этого города не найдена');
|
||||
return;
|
||||
}
|
||||
|
||||
const place = area?.areaName?.[0]?.value || city;
|
||||
const country = area?.country?.[0]?.value;
|
||||
const lines = [
|
||||
`Погода: ${place}${country ? `, ${country}` : ''}`,
|
||||
`${description(current)}, ${value(current, 'temp_C')} °C`,
|
||||
`Ощущается как ${value(current, 'FeelsLikeC')} °C`,
|
||||
`Влажность ${value(current, 'humidity')}% · ветер ${value(current, 'windspeedKmph')} км/ч`,
|
||||
'',
|
||||
'Прогноз:'
|
||||
];
|
||||
|
||||
for (const [index, day] of (data.weather || []).slice(0, 3).entries()) {
|
||||
const noon = day.hourly?.find(item => item.time === '1200') || day.hourly?.[4] || day.hourly?.[0];
|
||||
lines.push(
|
||||
`${dayLabel(day.date, index)}: ${description(noon)}, ${value(day, 'mintempC')}…${value(day, 'maxtempC')} °C`
|
||||
);
|
||||
}
|
||||
|
||||
await chat.sendText(lines.join('\n'));
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "pw.qlyra.weather",
|
||||
"name": "ИКАР Weather",
|
||||
"version": "1.0.0",
|
||||
"apiVersion": 1,
|
||||
"description": "Текущая погода и прогноз через wttr.in",
|
||||
"author": "ИКАР",
|
||||
"main": "main.js",
|
||||
"permissions": ["chat.write", "ui.notify", "network"],
|
||||
"commands": [
|
||||
{
|
||||
"name": "/weather",
|
||||
"description": "погода и прогноз для города",
|
||||
"handler": "weather",
|
||||
"arguments": [
|
||||
{"name": "city", "description": "название города", "rest": true}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user