How do I send an audio file from a url?,telebot - telebot

When sending an audio file to a user it sends an empty file? Why
import requests
url = "https://rr2---sn-o5f54xui5ai5qi5g5-nq5e.googlevideo.com/videoplayback?expire=1663630447&ei=D6goY5PcDJjwhgbypLNQ&ip=192.99.200.82&id=o-APi3v7YxiltNGhuudEU1QadeZGu43KlVFs9Xzj8cG52L&itag=249&source=youtube&requiressl=yes&vprv=1&mime=audio%2Fwebm&ns=EI4wJnvmPdR_yWihy94GX_YI&gir=yes&clen=1087015&dur=155.621&lmt=1636322375228392&keepalive=yes&fexp=24001373,24007246&c=WEB&rbqsm=fr&txp=5432434&n=vJaFhab1gWN74MHA&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgT5oP8aspSaeYQrHoI2xFwz4tA_1unBjxWArhIqRXI5UCIDxQkV9PN3DtA3QNtPKXLvKR0DGpoh9qAk5OzHU5JgjN&redirect_counter=1&rm=sn-t0al7s&req_id=dfa7083a5931a3ee&cms_redirect=yes&ipbypass=yes&mh=XX&mip=37.239.52.22&mm=31&mn=sn-o5f54xui5ai5qi5g5-nq5e&ms=au&mt=1663608542&mv=m&mvi=2&pl=24&lsparams=ipbypass,mh,mip,mm,mn,ms,mv,mvi,pl&lsig=AG3C_xAwRQIgGkeAL7toNeXZOgbrYyb0TkqKj593EfhIp269a_YFoAQCIQCtdiY5Z5YKkY6q4qRAUBfQJ2gN5ybZWMYDeg3PG2Kb9g%3D%3D"
files = {'audio': DataAudio}
payload = {
'chat_id': "1395609507",
'title': "jj",
'parse_mode': 'HTML',
'performer': 'YouTube'
}
resp = requests.post(
"https://api.telegram.org/bot{token}/sendAudio".format(token="xxxxxxxxx"),
data=payload,
files=files).json()
print(resp)
I used this but it doesn't send the audio file !
bot.send_voice(message.chat.id,url)
I hope you have a solution
Uncle the audio link used is from Youtube

you should use send_audio
https://pytba.readthedocs.io/en/latest/sync_version/index.html?highlight=audio#telebot.TeleBot.send_audio
also first save it then send that will be more smooth

Related

Parsing formdata from React using Serverless and API Gateway

I'm trying to upload a file and send data from a React frontend to a S3 bucket using an API Gateway/ Lambda function setup using the Serverless framework and I've been struggling with it for the last couple of days.
From the frontend I am using axios and creating a formdata to send a post request to the API like the following:
let formData = new FormData();
formData.append('imageFile', selectedImage);
formData.append('itemId', clubIdRef.current.value);
formData.append('itemDescription', itemDescRef.current.value);
axios.post(
baesURL+"/item/create", formData,
{headers: {
'Content-Type': 'multipart/form-data'
}}
).then((response) => {
console.log("response" + response)
console.log("response.data" + response.data)
})
Appending string attributes to the formdata feels off but the only way I could find to send data and an image at the same time was like the above.
Then to receive this data in the backend I've been using lambda-multipart-parser like the following:
const createItem = async (event) => {
const result = await multipartParser.parse(event);
const imageFile = result.imageFile;
const itemDescription = result.itemDescription;
where the result console logs as:
{
files: [],
imageFile: '[object File]',
itemId: '12',
itemDescription: "Description"
}
I can then store the imageFile successfully in S3 and generate the URL. Next, I create an Item object with the S3 url and id and description to store in dynamoDB. Everything works fine but when I open the S3 url the file is corrupted and just opens as a grey box instead of the actual image I uploaded.
This is how I am uploading the file using the s3 sdk
const AWS = require("aws-sdk");
const s3 = new AWS.S3();
const params = {
Bucket: BUCKET_NAME,
Key: `images/${directoryPath}/${id}.png`,
Body: imageFile,
ContentType: "image/png",
ACL : "public-read"
}
uploadResult = await s3.putObject(params).promise();
These are the things I've tried but still don't have any success uploading the correct image to my S3 bucket:
Looking and changing the BinaryMediaType of the API gateway but I can't find the settings under the API...
Tried using aws-lambda-multipart-parser but still wasn't able to add multipart/form-data binary media type and parse the full form data correctly
I know that I could first try to send a request directly from React to S3 to upload the image using aws-sdk in react to get a preSignedURL and attach that URL and make a POST request to my API Gateway simply parse the event.body without having to use a multipart form parser, but I want to avoid sending multiple requests if needed and handle everything in the backend.
Any suggestions would be highly appreciated!
It is quite hard to understand where is the problem with given context.
We have no idea which image format you are uploading, no idea how you store this image to S3.
My answer will try to cover these missing informations as it is a common mistake on S3 uploads.
S3 files are stored and returned with given ContentType.
You might check your S3 file's ContentType on AWS console.
Console > S3 > Select object (image) > Metadata > ContentType
I will suppose that image format is PNG and image data is correct and might be posted to S3 as is (from result).
S3Service.ts
import AWS, {S3} from "aws-sdk";
import {PutObjectRequest} from "aws-sdk/clients/s3";
import {PutObjectResponse} from "aws-sdk/clients/mediastoredata";
AWS.config.update({region: 'eu-west-3' });
const s3: S3 = new AWS.S3();
export class S3Service {
public static async putImage(key: string, data: string, contentType: string): Promise<PutObjectResponse> {
const s3Params: PutObjectRequest = {
Bucket: process.env.S3_BUCKET,
Key: key,
Body: data,
ContentType: contentType // <== I draw your attention here
}
return await s3.putObject(s3Params).promise()
}
}
index.ts
import { S3Service } from "service/aws/s3-service";
await S3Service.putImage(result.itemId + ".png", result.imageFile, "image/png");
A common mistake, which I assume might be the cause of your problem, is to forget content-type resulting in incorrect download format.

Does Google Script have an equivalent to python's Session object?

I have this python script and I want to get Google Script equivalent but I do not know how to "pass" whatever needs to be passed between next get or post request once I log in.
import requests
import json
# login
session = requests.session()
data = {
'LoginName': 'name',
'Password': 'password'
}
session.post('https://www.web.com/en-CA/Login/Login', data=data)
session.get('https://www.web.com//en-CA/Redirect/?page=Dashboard')
# get customer table
data = {
'page': '1',
'pageSize': '100'
}
response = session.post('https://www.web.com/en-CA/Reporting', data=data)
print(response.json())
I wonder if there is an equivalent to .session() object from python's requests module. I did search google but could not find any working example. I am not a coder so I dot exactly know that that .session() object does. Would it be enough to pass headers from response when making new request?
UPDATE
I read in some other question that Google might be using for every single UrlFetchApp.fetch different IP so login and cookies might not work, I guess.
I believe your goal as follows.
You want to achieve your python script with Google Apps Script.
Issue and workaround:
If my understanding is correct, when session() of python is used, the multiple requests can be achieved by keeping the cookie. In order to achieve this situation using Google Apps Script, for example, I thought that the cookie is retrieved at 1st request and the retrieved cookie is included in the request header for 2nd request. Because, in the current stage, UrlFetchApp has no method for directly keeping cookie and using it to the next request.
From above situation, when your script is converted to Google Apps Script, it becomes as follows.
Sample script:
function myFunction() {
const url1 = "https://www.web.com/en-CA/Login/Login";
const url2 = "https://www.web.com//en-CA/Redirect/?page=Dashboard";
const url3 = "https://www.web.com/en-CA/Reporting";
// 1st request
const params1 = {
method: "post",
payload: {LoginName: "name", Password: "password"},
followRedirects: false
}
const res1 = UrlFetchApp.fetch(url1, params1);
const headers1 = res1.getAllHeaders();
if (!headers1["Set-Cookie"]) throw new Error("No cookie");
// 2nd request
const params2 = {
headers: {Cookie: JSON.stringify(headers1["Set-Cookie"])},
followRedirects: false
};
const res2 = UrlFetchApp.fetch(url2, params2);
const headers2 = res2.getAllHeaders();
// 3rd request
const params3 = {
method: "post",
payload: {page: "1", pageSize: "100"},
headers: {Cookie: JSON.stringify(headers2["Set-Cookie"] ? headers2["Set-Cookie"] : headers1["Set-Cookie"])},
followRedirects: false
}
const res3 = UrlFetchApp.fetch(url3, params3);
console.log(res3.getContentText())
}
By this sample script, the cookie can be retrieved from 1st request and the retrieved cookie can be used for next request.
Unfortunately, I have no information of your actual server and I cannot test for your actual URLs. So I'm not sure whether this sample script directly works for your server.
And, I'm not sure whether followRedirects: false in each request is required to be included. So when an error occurs, please remove it and test it again.
About the method for including the cookie to the request header, JSON.stringify might not be required to be used. But, I'm not sure about this for your server.
Reference:
Class UrlFetchApp
You might want to try this:
var nl = getNewLine()
function getNewLine() {
var agent = navigator.userAgent
if (agent.indexOf("Win") >= 0)
return "\r\n"
else
if (agent.indexOf("Mac") >= 0)
return "\r"
return "\r"
}
pagecode = 'import requests
import json
# login
session = requests.session()
data = {
\'LoginName\': \'name\',
\'Password\': \'password\'
}
session.post(\'https://www.web.com/en-CA/Login/Login\', data=data)
session.get(\'https://www.web.com//en-CA/Redirect/?page=Dashboard\')
# get customer table
data = {
\'page\': \'1\',
\'pageSize\': \'100\'
}
response = session.post(\'https://www.web.com/en-CA/Reporting\', data=data)
print(response.json())'
document.write(pagecode);
I used this program

Where do I get `thread_ts` to start a Slack thread with an incoming webhook?

On Slack's incoming webhook documentation, they mention including the thread_ts in the request body to start a thread.
{
"text": "Hello, world.",
"thread_ts": "12345.6789"
}
When I make the POST request to my incoming webhook url, the response body does not include the thread_ts. I was expecting the thread_ts to be in the response body, but the response body just says ok and does not include any json.
Is it possible to get the thread_ts without another app or authentication token? Do I have to use another Slack API? I only have the incoming webhook configured right now.
As a side note, if this is easier to do with Slack's new Block Kit API, that would work as well.
To take full control of all messaging features of Slack including threads you want to use the API.
When posting messages with chat.postMessage you get the thread_ts value and can start creating threads.
Also check out this official documentation on threads. It clears up a lot.
I am not an export on the new blocks yet, but as far as I understand it replaced the attachments and provides a more flexible way for message layouts. It does however not change the way threading works.
from slack_sdk import WebClient
slack_client = WebClient(token='token_value')
response = slack_client.chat_postMessage(channel=receiver, text=message)
print(response.data)
thread_ts = response.data['ts']
In case of Bolt api (js) you can check ts value from callback arguments.
app.message(
"link please",
async ({ message, say }) => { // You can also get ts from `payload`
console.log(message);
await say({
text: "you can check this link",
thread_ts: message.ts, // you can get ts from message
});
});
message content:
{
client_msg_id: 'xxxxx',
type: 'message',
text: 'xxxx',
user: 'UxxR',
ts: '1650249299.335499',
team: 'xxxx',
blocks: [ { type: 'rich_text', block_id: 'adOR', elements: [Array] } ],
thread_ts: '1650249116.347219',
parent_user_id: 'UxxxxxR',
channel: 'C01TNEN8SSK',
event_ts: '1650249299.335499',
channel_type: 'group'
}

Nativescript send camera capture to server

In my Nativescript application I would like to capture an image using the camera module and then send the bytes directly to the server via http call.
Here is my code (incomplete for brevity):
var cameraModule = require("camera");
var http = require("http");
...
cameraModule.takePicture().then(function (img) {
// how to extract the actual bytes from img???
http.request({
url: some_url,
method: "POST",
headers: { "Content-Type": "application/octet-stream" },
content: ???
});
});
Is there a way to do that?
I was looking at nativescript-background-http and it seems to fit my requirements exactly, but the example shows the file being loaded from a path only. I did not have any luck making this to work on iOS.
Any help is greatly appreciated.
Thank you.
A couple things;
"img" is actually a image source.
At this point the built in HTTP module does not support direct binary transfers, so we need to convert it to something that can be sent over the wire. So base64 is a text representation that can support binary, and it is a common encoding/decoding method.
Since we already have it as a image source we just use the cool toBase64String ability which give us the Base 64 data.
So here is basically is how I would do it (tested under android).
var cameraModule = require('camera');
var some_url="http://somesite";
// img is a image source
cameraModule.takePicture().then(function (img) {
// You can use "jpeg" or "png". Apparently "png" doesn't work in some
// cases on iOS.
var imageData = img.toBase64String("jpeg");
http.request({
url: some_url,
method: "POST",
headers: { "Content-Type": "application/base64" },
content: imageData
}).then(function() {
console.log("Woo Hoo, we sent our image up to the server!");
}).catch(function(e) {
console.log("Uh oh, something went wrong", e);
});
});
There are a few ways to do this. If your backend can take a base64 string you can use the image-source class and manipulate the data. I'm on my phone or I'd mock up a sample. It really depends what you expect on the server to be honest but most options are possible with NativeScript using the image-source and ui/image component.
http://docs.nativescript.org/api-reference/classes/_image_source_.imagesource.html#tobase64string
Going from memory here but try this when you get the (IMG) back.
var data = img.tobase64string(); that should give you a base 64 string of the image.
Just found this awesome sample from another question https://stackoverflow.com/a/37815237/1893557
This will work to send the file after you save it locally and uses the background-http plugin.

Upload files asynchronously (AJAX) with HTTP/1.1 PUT method, why not?

Uploading files via PUT method, even binary or text, via a "normal web browser" is possible.
Why many people are just saying, that is not possible ?
Sample code with jQuery and PHP.
$(document).ready(function() {
$("#uploadbutton").click(function() {
var filename = $("#file").val();
$.ajax({
type: "PUT",
url: "addFile.do",
enctype: 'multipart/form-data',
data: {file: filename},
success: function(){
alert( "Data Uploaded: ");
}
});
});
});
On the server side just read the STDIN stream like
<?php
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
/* Open a file for writing */
$fp = fopen("myputfile.ext", "w");
/* Read the data 1 KB at a time
and write to the file */
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
/* Close the streams */
fclose($fp);
fclose($putdata);
?>
{file: filename}
When you upload a file, you have to upload the file. Telling the server what the local filename is… isn't enough.
JavaScript, running in a web browser in a standard security context, doesn't have access to read the data in the file from the user's hard disk.
Since you can't get the data, you can't upload it.
For your solution specifically, mainly because the PUT method (verb) is not supported by all browsers, especially older ones, so this solution won't work for everyone.
The topic has come up previously as well, though not exactly the same, some answers are examples of where PUT and DELETE don't work.
The documentation for $.ajax() mentions this as well:
type
Default: 'GET'
The type of request to make ("POST" or "GET"), default is "GET".
Note: Other HTTP request methods, such as PUT and DELETE, can also be used here, but they are not supported by all browsers.

Resources