Add text-to-speech via Piper TTS
All checks were successful
ci/woodpecker/push/deploy Pipeline was successful

Send text message → Piper TTS → WAV → OGG Opus → voice reply.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Mikhail Kilin
2026-02-19 13:24:41 +03:00
parent 213eabb026
commit 86acdfab28
4 changed files with 154 additions and 19 deletions

View File

@@ -15,6 +15,7 @@ pub const VideoNote = struct {
pub const Message = struct {
message_id: i64,
chat: struct { id: i64 },
text: ?[]const u8 = null,
voice: ?Voice = null,
video_note: ?VideoNote = null,
};
@@ -134,4 +135,35 @@ pub const TelegramBot = struct {
const resp = http.httpPostJson(self.allocator, url, json_body) catch return;
self.allocator.free(resp);
}
pub fn sendVoice(self: *TelegramBot, chat_id: i64, ogg_path: []const u8, reply_to: ?i64) !void {
const url = try std.fmt.allocPrint(self.allocator, "{s}/sendVoice", .{self.api_base});
defer self.allocator.free(url);
const chat_id_str = try std.fmt.allocPrint(self.allocator, "{d}", .{chat_id});
defer self.allocator.free(chat_id_str);
var fields_buf: [2][2][]const u8 = undefined;
var field_count: usize = 1;
fields_buf[0] = .{ "chat_id", chat_id_str };
var reply_str: ?[]u8 = null;
defer if (reply_str) |s| self.allocator.free(s);
if (reply_to) |r| {
reply_str = try std.fmt.allocPrint(self.allocator, "{d}", .{r});
fields_buf[1] = .{ "reply_to_message_id", reply_str.? };
field_count = 2;
}
const resp = try http.httpPostMultipart(
self.allocator,
url,
"voice",
ogg_path,
"voice.ogg",
fields_buf[0..field_count],
);
self.allocator.free(resp);
}
};