I want to make a bot that can restrict new user that join to the group, below is my code, but when I run this, it seemed that it is not working. I guess I misunderstood the way of how 'chatpermission' work, but can't find it.
Here is the 'restrict' method from telegram web: link
(I had already set the telegram webhook to this google app script)
e={
message={
new_chat_member={
language_code=zh-hans,
is_bot=false,
username=jinyulink34,
first_name=Jinyulink,
id=1.292889543E9
},
date=1.58726641E9,
from={
language_code=zh-hans,
is_bot=false,
username=Jinyulink,
first_name=Jinyulinm,
id=9.50729481E8
},
message_id=222.0,
new_chat_participant={
username=jinyulink34,
first_name=Jinyulink,
id=1.292889543E9,
language_code=zh-hans,
is_bot=false
},
new_chat_members=[
Ljava.lang.Object;#6957c279,
chat={
type=supergroup,
username=jinyulin,
id=-1.001365615879E12,
title=Test
}
},
update_id=3995756.0
}
function identificar(e){
var message = e.message.text;
if (e.message.new_chat_members){
var ChatPermissions = {
"can_send_messages":false,
"can_send_media_messages":false,
"can_send_other_messages":false,
"can_add_web_page_previews":false,
"can_send_polls":false,
"can_change_info":false,
"can_invite_users":false,
"can_pin_messages":false
}
var userid=JSON.parse(e.message.from.id);/*logger.log(userid)->shows(950729481)*/
var restrict = {
"method": "restrictChatMember",
"chat_id": String(e.message.chat.id),
"user_id": userid,
"permissions":JSON.stringify(ChatPermissions)
}
start(restrict);
}
}
function start(payload) {
var data = {
"method": "post",
"payload": payload
}
var returned = UrlFetchApp.fetch("https://api.telegram.org/bot-token/", data);
}
I'm getting the following error:
{"ok":false,"error_code":400,"description":"Bad Request: wrong user_id specified"}
Related
I'm creating a feedback bot that will send out direct messages to individuals as soon as an event on their calendar ends. For this, i've developed most of the code using appscript. I got the calendar api trigger working and i can get the same functionality working using /slash commands, but what i want is to automate this process, in that, the bot will automatically send out the message on the calendar trigger.
I'm not sure how to get this to work as i didn't find any examples or documentation to do the same. I read somewhere that google chat api doesn't allow proactively sending messages directly to users, but i have seen examples of it working.
When i try to send the message using the appscript chat api sdk, it doesn't send any message, although the flow runs successfully as i can see from the logs.
When i try using google chat rest api i'm facing errors when trying to send out a message.
The error for rest api, the error i'm seeing is :
12:10:32 PM Error
Exception: Request failed for https://chat.googleapis.com returned code 400. Truncated server response: {
"error": {
"code": 400,
"message": "Message cannot have cards for requests carrying human credentials.",
"status": "INVALID_ARGUMEN... (use muteHttpExceptions option to examine full response)
showFeedbackMessageRest # feedback.gs:105
pubsub_subscribe # feedback.gs:42
the code for the pub/sub subscriber is :
function pubsub_subscribe(e){
var service = getService();
if (!service.hasAccess()) {
var authorizationUrl = service.getAuthorizationUrl();
console.log('Authorize PubSub Service First : !!!!!!!!!!!!!!!!');
console.log(authorizationUrl);
showFeedbackMessageRest(e, {'auth_url' : authorizationUrl});
}else{
console.log('PubSub has Access!')
var project_id = get_property('PROJECT_ID');
// var topic = get_property('TOPIC');
var subscriber = get_property('SUBSCRIBER');
var url = `https://pubsub.googleapis.com/v1/projects/${project_id}/subscriptions/${subscriber}:pull`
var body = {
returnImmediately: true,
maxMessages: 1
}
var response = UrlFetchApp.fetch(url, {
method: "POST",
contentType: 'application/json',
muteHttpExceptions: true,
payload: JSON.stringify(body),
headers: {
Authorization: 'Bearer ' + getService().getAccessToken()
}
});
var result = JSON.parse(response.getContentText());
console.log(JSON.stringify(result));
console.log(Object.keys(result).length);
if (Object.keys(result).length > 0){
var decoded = Utilities.base64Decode(result.receivedMessages[0].message.data);
var event_details = JSON.parse(Utilities.newBlob(decoded).getDataAsString());
var popup_obj = {
'summary' : event_details.EventTitle
};
console.log(popup_obj);
return showFeedbackMessageRest(e, popup_obj);
}else{
console.log('No Recent Messages!');
}
}
}
and the code to send the message using chat rest api is :
function showFeedbackMessageRest(e, event) {
var chat_service = getChatService()
var message = {};
if (!chat_service.hasAccess()) {
var authorizationUrl = chat_service.getAuthorizationUrl();
console.log('Authorize Chat Service First : !!!!!!!!!!!!!!!!');
console.log(authorizationUrl);
}else{
console.log('Chat App Has Access!');
if (event.hasOwnProperty('summary')){
message = {
"text" : `Provide Feedback For : ${event.summary}`
};
}else{
message = {
"cards_v2": [{
"card_id": "feedbackMessage",
"card": {
"header": {
"title": `Provide Feedback For : ${event.summary}`,
"subtitle": `This meeting just ended, provide feedback for the organizers to organize meetings more effectively.`,
"imageUrl": "https://raw.githubusercontent.com/google/material-design-icons/master/png/social/poll/materialicons/24dp/2x/baseline_poll_black_24dp.png",
"imageType": "CIRCLE"
},
"sections": [
{
"widgets": [
{
"buttonList": {
"buttons": [
{
"text": "Give Feedback",
"onClick": {
"action": {
"function": "promptQuestion",
"interaction": "OPEN_DIALOG"
}
}
}
]
}
}
]
}
]
}
}]
};
}
}
var url = 'https://chat.googleapis.com/v1/' + `${user_dm_space_name}` + '/messages';
UrlFetchApp.fetch(url, {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + chat_service.getAccessToken() },
contentType: 'application/json',
payload: JSON.stringify(message),
});
}
I even tried to send a simple text message as according to the error, the cards are not allowed to be sent, but i'm getting this error :
12:30:36 PM Error
Exception: Request failed for https://chat.googleapis.com returned code 403. Truncated server response: {
"error": {
"code": 403,
"message": "This API is not accessible for external HTTP caller.",
"status": "PERMISSION_DENIED"
}
}
(use muteHttpExceptions option to examine full response)
showFeedbackMessageRest # feedback.gs:105
pubsub_subscribe # feedback.gs:42
I'm trying to use answerInlineQuery method but i have an error:
function(inlineQuery) {
var url = API_URL + '/answerInlineQuery',
params = {};
var inline_query_id = inlineQuery.id;
var results = [{
"type":"location",
"id":"1",
"latitude":4.710989,
"longitude":-74.072092,
"title":"Bogotá"
}];
params.inline_query_id = inline_query_id;
params.results = results;
request('post', url, JSON.stringify(params), function(data) {
if(data && data.ok){
console.log('answerInlineQuery enviado');
}else{
console.log('Error enviando answerInlineQuery: ' + JSON.stringify(data));
}
});
};
The parameters that i'm sending are (formated with JSON.stringify):
{
"inline_query_id": "32021086267134929",
"results": [
{
"type": "location",
"id": "1",
"latitude": 4.710989,
"longitude": -74.072092,
"title": "Bogotá"
}
]
}
I'm using Javascript with a POST request function to the Telegram Bot API and the error that i have is this:
Error enviando answerInlineQuery: {"ok":false,"error_code":400,"description":"[Error : 400 : Bad Request: QUERY_ID_INVALID]"}
I just saw this question: telegram bot api python error but i don't know how json.dumps works in python. I need to know the correct "params" format that i need to send to the API.
you should send notify max 15 sec after inline keyboard pushed
I had 2 problems, no stringfy the "results" and stringfy the "params" that was wrong.
I just needed stringfy the "results" and not stringfy the "params"
I am getting the correct response after doing some POC. I am using Java com.github.pengrad.
Below the code:
GetUpdatesResponse updatesResponse = bot.execute(new GetUpdates());
List updates = updatesResponse.updates();
for(Update update:updates){
InlineQuery inlineQuery = update.inlineQuery();
System.out.println(update);
System.out.println(inlineQuery);
System.out.println("----------------");
if(inlineQuery!=null) {
InlineQueryResult r1 = new InlineQueryResultPhoto("AgADBQADrqcxG5q8tQ0EKSz5JaZjzDWgvzIABL0Neit4ar9MsXYBAAEC", "https://api.telegram.org/file/bot230014106:AAGtWr8xUCqUy8HjSgSFrY3aCs4IZs00Omg/photo/file_1.jpg", "https://api.telegram.org/file/bot230014106:AAGtWr8xUCqUy8HjSgSFrY3aCs4IZs00Omg/photo/file_1.jpg");
BaseResponse baseResponse = bot.execute(new AnswerInlineQuery(inlineQuery.id(), r1)
.cacheTime(6000)
.isPersonal(true)
.nextOffset("offset")
.switchPmParameter("pmParam")
.switchPmText("pmText"));
System.out.println(baseResponse.isOk());
System.out.println(baseResponse.toString());
System.out.println(baseResponse.description());
}
}
Below the console output:
Update{update_id=465103212, message=null, edited_message=null, inline_query=InlineQuery{id='995145139265927135', from=User{id=231700283, first_name='Test', last_name='test', username='null'}, location=null, query='hi', offset=''}, chosen_inline_result=null, callback_query=null}
InlineQuery{id='995145139265927135', from=User{id=231700283, first_name='test', last_name='test', username='null'}, location=null, query='hi', offset=''}
true
BaseResponse{ok=true, error_code=0, description='null'}
null## Heading ##
And I am getting proper response in my mobile telegram app also.
I need to send print Job to my printer using Google Cloud Print. It is a Classic Printer Named RISO ComColor 7150. My Code in Apps Script is as follows:-
function printGoogleDocument(docID, printerID, docName , type , duplex) {
var ticket = {
version: "1.0",
print: {
color: {
type: type,
vendor_id: "Color"
},
duplex: {
type: duplex
}
}
};
var payload = {
"printerid" : printerID,
"title" : docName,
"content" : DriveApp.getFileById(docID).getBlob(),
"contentType": "application/pdf",
"ticket" : JSON.stringify(ticket),
"pages" : "1,2"
};
var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', {
method: "POST",
payload: payload,
headers: {
Authorization: 'Bearer ' + getCloudPrintService().getAccessToken()
},
"muteHttpExceptions": true
});
response = JSON.parse(response);
if (response.success) {
Logger.log("%s", response.message);
} else {
Logger.log("Error Code: %s %s", response.errorCode, response.message);
}
}
problem is When i am Sending type to STANDARD_COLOR and duplex to NO_DUPLEX than it is Working fine but when i change them to MONOCHROME and DUPLEX than it is Giving me Color print with no duplex again. Also i am Sending Page Number but it Prints whole pdf instead of giving me print of specific page.
Can Anybody tell me what i am doing worng here??
Thanks in Advance.
you can set all the things in print job ticket, no need to specify the page number outside ticket.
Here ,a CJT am recommending ,
var ticket = "{\"version\":\"1.0\",\"print\":{\"color\":{\"vendor_id\":\"1\",\"type\":1},\"duplex\":{\"type\":0},\"page_orientation\":{\"type\":"0"},\"copies\":{\"copies\": "2"},\"fit_to_page\":{\"type\":3},\"page_range\":{\"interval\":[{\"start\": "1",\"end\":"2"}]},\"media_size\":{\"width_microns\":210000,\"height_microns\":297000,\"is_continuous_feed\":false,\"vendor_id\":\"9\"},\"collate\":{\"collate\":false},\"reverse_order\":{\"reverse_order\":false}}}";
so you can specify duplex, page limit..etc
It would be nice if you can go this documentation.
https://developers.google.com/cloud-print/docs/cdd#pts
And for duplex,its an integer expecting, you can set this way..if NO_DUPLEX is needed you need to send 0,
NO_DUPLEX = 0;
LONG_EDGE = 1;
SHORT_EDGE = 2;
I am trying to comment and rate a comment via API but the resource is always
canRate: false and canReply: false
I
I've tried through google javascript client and http get request, but nothing seems to be working.
$http.get('https://www.googleapis.com/youtube/v3/commentThreads', {
params: {
key: API_KEY,
part: 'snippet',
textFormat: 'plainText',
videoId: VIDEO_ID,
order: 'relevance'
}
}).success(function(response) {
$scope.comments = response.items;
$log.debug($scope.comments);
//var author = item.snippet.topLevelComment.snippet.authorDisplayName;
//var comment = item.snippet.topLevelComment.snippet.textDisplay;
//var nextToken = results.nextPageToken;
//var totalRep = item.snippet.totalReplyCount;
//var parent = item.snippet.topLevelComment.id;
})
.error(function(error) {
$log.error(error);
})
This is what I'm using, I can list them perfectly (even using v3/comments) but can't reply neither rate a comment, this is what I'm using
gapi.client.load('youtube', 'v3', function () {
$scope.selectedComment.snippet.viewerRating = 'like';
var request = gapi.client.youtube.commentThreads.update({
part: "snippet",
body: $scope.selectedComment
});
request.execute(function(response) {
$log.debug(response);
});
});
At the body part I've also tried this
body: {
id: $scope.selectedCommentId,
'snippet': {
'viewerRating': 'like'
}
}
But I get this error
404 The specified comment thread could not be found. Check the value
of the id property in
the request body to ensure that it is correct
You can replay the comment
POST https://www.googleapis.com/youtube/v3/comments?part=snippet&access_token={YOUR_API_KEY}
body
{
"snippet": {
"parentId": "parentCommentID",
"textOriginal": "yoursComment"
}
}
You can get more info here
https://developers.google.com/youtube/v3/docs/comments/insert#examples
I have written a series of Parse Promises and am now getting error 141 when I make a request to this cloud code function. I have tried placing success: / error: all over the function where I think they belong based on the Parse DOCS.
Request
{
"projectDescription": "Testing saveProject",
"projectTitle": "This is only a test, in the event of a real post this will have an actual description",
"isEmailEnabled": true,
"shareEmails": [
"max#gmail.com",
"nat#gmail.com",
"noob#gmail.com"
],
"userId": "sLmOf4fZFL"
}
Parse.Cloud.define("saveProject", function(request, response) {
var emails = request.params.shareEmails;
var user = request.params.userId;
var projectDescription = request.params.projectDescription;
var projectTitle = request.params.projectTitle;
var emailStatus = request.params.isEmailEnabled;
var ProjectClass = Parse.Object.extend("Project");
var EmailsClass = Parse.Object.extend("Email");
var EmailsClassAssignment = Parse.Object.extend("EmailAssignment");
var project = new ProjectClass();
var projectO;
project.set("title", projectTitle);
project.set("createdBy", {
"__type": "Pointer",
"className": "_User",
"objectId": user
});
project.set("description", projectDescription);
project.set("status", true);
project.set("emailShareEnabled", emailStatus);
project.save().then(function(results) {
projectO = results;
console.log(projectO);
return Parse.Promise.when(emails.map(function(emailAddress) {
var email = new EmailsClass();
email.set("address", emailAddress);
return email.save();
}));
}).then(function() {
return Parse.Promise.when(emails.map(function(emailQuery) {
var queryEmail = new Parse.Query("Email");
queryEmail.equalTo("address", emailQuery);
return queryEmail.find().then(function(results) {
var emailJSON = results[0].toJSON();
var emailObjectId = emailJSON.objectId;
var projectJSON = projectO.toJSON();
var projectId = projectJSON.objectId;
var assignment = new EmailsClassAssignment();
assignment.set("createdBy", {
"__type": "Pointer",
"className": "_User",
"objectId": user
});
assignment.set("email", {
"__type": "Pointer",
"className": "Email",
"objectId": emailObjectId
});
assignment.set("project", {
"__type": "Pointer",
"className": "Project",
"objectId": projectId
});
assignment.save(null, {
success: function() {
console.log("Successfully saved project");
},
error: function(error) {
console.log("There was an error saving" + error.message);
}
});
});
}));
}).then( function() {
response.success();
});
});
The basic ideas look okay, but the code is kind of a jumble of callback parameters and promises. I took the liberty of refactoring into simpler, promise-returning logical chunks so we could see what's going on.
You highlighted the .map functions in the post. Not sure what the issue was there, so the code I suggest uses underscorejs, which can be easily included in the cloud as follows:
var _ = require('underscore');
First, return a promise to save a "project" given most of the params to your cloud function:
function createProject(params) {
var ProjectClass = Parse.Object.extend("Project");
var project = new ProjectClass();
var emails = request.params.shareEmails;
var user = request.params.userId;
var projectDescription = request.params.projectDescription;
var projectTitle = request.params.projectTitle;
var emailStatus = request.params.isEmailEnabled;
project.set("title", projectTitle);
project.set("createdBy", {
"__type": "Pointer",
"className": "_User",
"objectId": user
});
project.set("description", projectDescription);
project.set("status", true);
project.set("emailShareEnabled", emailStatus);
return project.save();
}
Next, create "Email"'s (which are objects) given an array of email address strings. (You would do well to more carefully distinguish the objects and the strings in your naming, but I tried to hew to original nomenclature in the code)
function createEmails(emails) {
var EmailsClass = Parse.Object.extend("Email");
var toSave = _.map(emails, function(emailAddress) {
var email = new EmailsClass();
email.set("address", emailAddress);
return email;
});
// like the when() function, but (possibly) fewer requests
return Parse.Object.saveAll(toSave);
}
This is where the original code took a turn for the worse. In it, the code just finished creating the Email objects, then for some reason, it attempts to query those objects. But we have them in hand already, on the fulfullment of the promises to save.
The method below, takes already built email objects (named pedantically, to emphasize that they are objects) and other ingredients to an "EmailClassAssignment". Notice how we can assign pointers directly with objects when we have a PFObject in hand:
function createEmailClassAssignments(emailObjects, project, userId) {
var EmailsClassAssignment = Parse.Object.extend("EmailAssignment");
var toSave = _.map(emailObjects, function(emailObject) {
var assignment = new EmailsClassAssignment();
// the real objects can be used as parameters to set for pointer columns
assignment.set("email", emailObject);
assignment.set("project", project);
// we only have the userId, not a user object, so we can either query
// for the user or take the shortcut that you've been taking
project.set("createdBy", {
"__type": "Pointer",
"className": "_User",
"objectId": user
});
return assignment;
});
return Parse.Object.saveAll(toSave);
}
With all that done, the cloud function becomes more legible:
Parse.Cloud.define("saveProject", function(request, response) {
var project;
createProject(params).then(function(result) {
project = result;
return createEmails(request.params.shareEmails);
}).then(function(emailObjects) {
return createEmailClassAssignments(emailObjects, project, request.params.userId);
}).then(function() {
console.log("Successfully saved project");
// I took the liberty of returning the new project to the caller
response.success(project);
}, function(error) {
console.log("There was an error saving" + error.message);
resoonse.error(error);
});
});
CAUTION: obviously, there's no way for me to test any of the foregoing. I strongly urge you to test the functions yourself, preferably individually before expecting the combination to work. Hopefully, the refactor demonstrates a cleaner way to use promises and a reasonable decomposition of parts to test and use individually.
From the looks of your code, you simply need to add a return in front of assignment.save() as you aren't waiting for that to finish otherwise.
Lastly you should add an error catcher at the very end:
.then(null, function(error) {
console.log(error);
response.error(error);
});