CREATE OR REPLACE PROCEDURE send_file_to_telegram(
p_wallet in varchar2, -- Oracle wallet location where Telegram certificate must be imported to (as trusted, ex: api.telegram.org.p7c )
p_token in varchar2, -- given token without quotes, ex.: 6794299551:AAE9YGyFQT7peVRvrctYgWocJHD04Q66LVc
p_chat_id in varchar2, -- full chat identified, usually numeric (add -100 before id), ex: -1001525901058
p_directory in varchar2, -- Oracle directory where filename is located
p_file_name in varchar2, -- name of the file to be send
p_caption in varchar2 default null -- caption as a text to send, without quotes
) AS
l_boundary VARCHAR2(100) := '----WebKitFormBoundary7MA4YWxkTrZu0gW';
l_crlf VARCHAR2(2) := CHR(13) || CHR(10);
l_req UTL_HTTP.req;
l_resp UTL_HTTP.resp;
l_buffer RAW(32767);
l_position INTEGER := 1;
l_amount INTEGER := 32767;
l_file_length INTEGER;
v_directory varchar2(100) := nvl(p_directory,'BOT_DIR');
v_url VARCHAR2(1000) := 'https://api.telegram.org/bot' || p_token || '/sendDocument'; -- Construct the API URL
v_source BFILE; -- to hold source file (as binary file variable)
l_header VARCHAR2(32767);
BEGIN
-- load source file into BFILE
v_source := bfilename(v_directory, p_file_name);
dbms_lob.fileopen(v_source, dbms_lob.file_readonly);
l_file_length := DBMS_LOB.getlength(v_source);
-- Constructing head part of the request (form-data)
l_header := '--' || l_boundary || l_crlf ||
'Content-Disposition: form-data; name="chat_id"' || l_crlf || l_crlf ||
p_chat_id || l_crlf ||
'--' || l_boundary || l_crlf ||
'Content-Disposition: form-data; name="caption"' || l_crlf || l_crlf ||
p_caption || l_crlf ||
'--' || l_boundary || l_crlf ||
'Content-Disposition: form-data; name="document"; filename="'||p_file_name||'"' || l_crlf ||
'Content-Type: application/octet-stream' || l_crlf || l_crlf;
-- Set wallet before any requests are made
utl_http.set_wallet(path => 'file:'||p_wallet);
l_req := UTL_HTTP.begin_request(
url => v_url,
method => 'POST',
http_version => 'HTTP/1.1'
);
UTL_HTTP.set_header(l_req, 'Content-Type', 'multipart/form-data; boundary=' || l_boundary);
UTL_HTTP.set_header(l_req, 'Transfer-Encoding', 'chunked');
UTL_HTTP.write_text(l_req, l_header);
-- sending file in raw chunks (read next chunk from file into a buffer then send raw buffer contents )
WHILE l_position <= l_file_length LOOP
l_amount := LEAST(32767, l_file_length - l_position + 1);
DBMS_LOB.READ(v_source, l_amount, l_position, l_buffer);
UTL_HTTP.write_raw(l_req, l_buffer);
l_position := l_position + l_amount;
END LOOP;
DBMS_LOB.FILECLOSE(v_source);
-- Send footer (end of the payload)
UTL_HTTP.write_text(l_req, l_crlf || '--' || l_boundary || '--' || l_crlf);
-- Read response
l_resp := UTL_HTTP.get_response(l_req);
UTL_HTTP.end_response(l_resp);
EXCEPTION
WHEN OTHERS THEN
IF DBMS_LOB.FILEISOPEN(v_source) = 1 THEN
DBMS_LOB.FILECLOSE(v_source);
END IF;
RAISE;
END;