Appengine channels automatically disconnected on production - python

On production, a soon as I open a channel with the javascript, it disconnects a seccond after.
Everything works super fine on devserver. The callback works on the server but not on the client. We are using flask, backbone, requirejs and sourcemap.
Client code:
window.channel = new goog.appengine.Channel(window.PLAY_SETTINGS.CHANNEL_TOKEN);
window.gae_websocket = window.channel.open({
onopen: function() {
return console.log('onopen');
},
onclose: function() {
return console.log('onclose');
},
onerror: function() {
return console.log('onerror');
},
onmessage: function() {
return console.log('onmessage');
}
});
Server code:
class Connection(ndb.Model):
user_key = ndb.KeyProperty()
scope = ndb.IntegerProperty(indexed=True, choices=range(0, 2))
target_key = ndb.KeyProperty(indexed=True) # Event ou debate
channel_id = ndb.StringProperty(indexed=True)
#staticmethod
def open_channel():
channel_id = str(uuid4())
channel_token = channel.create_channel(client_id=channel_id, duration_minutes=480)
return channel_token, channel_id
Logs from the appengine production console.
The client callbacks (js) dont works. These are the server callbacks that create the logs:
#app.route('/_ah/channel/disconnected/', methods=['POST'])
def channel_disconnection():
client_id = request.form.get('from')
ndb.delete_multi(Connection.query(Connection.channel_id == client_id).fetch(keys_only=True))
logging.info("Channel closed : %s" % client_id)
return make_response('ok', '200')
#app.route('/_ah/channel/connected/', methods=['POST'])
def channel_connection():
client_id = request.form.get('from')
logging.info("Channel open : %s" % client_id)
return make_response('ok', '200')

Related

socket.io client can't callback(wait for response) to nodejs sever

I tried to make the server to wait for response from client(web app) that take 'fall' event call form server. But it wouldn't wait. Also the server will have to received 'fall' event from another client(fall detection:python) then that client have to wait for response from the server, but now it(fall detection) will call out fall event all the time when it detected fall.
//Client code
socket.on('fall', (data, callback) => {
if (confirm("fall detect " + data)) {
alarmSound.play();//function to play sound
setTimeout(function() {}, 5000);
}
callback({
"response" : "ok",
});
});
//Nodejs Server code
const socketio = require('socket.io');
const io = socketio(server);
io.on("connection", function(socket) {
console.log("New user connected.", socket);
socket.on('Fall', (data, callback) => {
const rpiID = data.rpiID;
console.log("Fall detected at Cam ", rpiID);
io.emit('fall', rpiID, function (cdata) {
while(!cdata);
});
// socket.emit('image', { image: true, buffer: buf.toString('base64') });
callback({
status: "ok",
});
});
#socketio loop test code(python)
import socketio
sio = socketio.Client()
host = 'http://localhost:8080'
rpiID = '3'
while True:
sio.connect(host)
#sio.event
def connect():
print("Connected to", host)
#sio.event
def connect_error():
print("Connection failed")
#sio.event
def disconnect():
print("Disconnected from", host)
print('My sio id :', sio.sid)
sio.emit('Fall', {'rpiID' : rpiID})
sio.disconnect();

how to add many ids to one list?

I have a code that writes down the user id and the name of the streamer, when the streamer starts the stream, the user who entered the command is notified.
How can I correctly add all user IDs of users so that it works for everyone, and not just for one
import requests
import pymongo
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
TOKEN = ''
bot = Bot(token=TOKEN)
dp = Dispatcher(bot)
scheduler = AsyncIOScheduler(timezone="Europe/Kiev")
client = pymongo.MongoClient('')
db = client['Users']
collection = db['twitch']
def add_user(streamer_name, chat_id):
collection.update_one({
"_id": streamer_name
}, {"$set": {
'online': '-',
'chat_id': chat_id
}}, upsert=True)
def set_online(streamers):
collection.update_one({
'_id': streamers
}, {'$set': {
'online': 'True'
}})
def set_offline(streamers):
collection.update_one({
'_id': streamers
}, {'$set': {
'online': 'False'
}})
async def check(streamer_name, chat_id):
client_id = ''
client_secret = ''
body = {
'client_id': client_id,
'client_secret': client_secret,
"grant_type": 'client_credentials'
}
r = requests.post('https://id.twitch.tv/oauth2/token', body)
keys = r.json()
headers = {
'Client-ID': client_id,
'Authorization': 'Bearer ' + keys['access_token']
}
all_records = collection.find()
users = list(all_records)
for i in users:
streamers = i['_id']
send_users = i['chat_id']
online = i['online']
stream = requests.get('https://api.twitch.tv/helix/streams?user_login=' + streamers, headers=headers)
stream_data = stream.json()
if len(stream_data['data']) == 1:
live = (streamers + ' is live: ' + stream_data['data'][0]['title'])
if online == 'False':
await bot.send_message(send_users, live)
set_online(streamers)
if online == 'True':
print('streamer online')
else:
set_offline(streamers)
scheduler.add_job(check, "interval", seconds=5, args=(streamer_name, chat_id))
#dp.message_handler(commands='check')
async def check_stream(message: types.Message):
streamer_name = message.text[7:]
chat_id = message.chat.id
add_user(streamer_name, chat_id)
await check(streamer_name, chat_id)
if __name__ == "__main__":
scheduler.start()
executor.start_polling(dp, skip_updates=True)
And when the streamer starts the stream, then many messages come in and not just one.

Facebook Graph API | Request [400] Errorr

I create a bot to monitor the comment if there is any new comment and if so it will automatically private_replies them But instead i got a Request [400] Error instead.
def monitor_comment():
print("Bot is monitoring comments")
time.sleep(5)
comment_data = graph.get_connections(COMBINED_POST_ID_TO_MONITOR,"comments",order='reverse_chronological')
commends = []
for comment in comment_data['data'][:10]:
commends.append (comment)
data = commends[0]['id']
data_converted = str(data)
#time.sleep(5)
print(data)
return data_converted
def private_reply(comment_ids):
url = "https://graph.facebook.com/v12.0/me/messages?"
access = {"access_token":Page_Token}
params = {
"recipient": {
"comment_id": comment_ids
},
"message": {
"text":"Testing Private_Replies"
}
request = requests.post(url=url, files=access, json=params)
print(request)
This is the logs
{"error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500,"fbtrace_id":"AMCiqy1Aw8CyODPlUBE1b98"}}

Can't get FCM push notifications from my server on iOS (working on Android)

I'm new to iOS/Swift and can't get push notifications working. I have configured my server backend to push notifications to my app when some action happens. I have configured a data notification trough FCM because I need some custom data in the notification to open one activity/view or another. This is the code used to send the notification (python/django):
registration_id = profiletarget.device_token
message_title = "Ha llegado tu turno"
message_body = "Entra y escribe en el relato para el que estás en cola"
data_message = {
"title" : "¿Listo para escribir?",
"body" : "Ha llegado tu turno para escribir en el relato. Recuerda que tienes un minuto para aceptar tu turno y 3 para escribir.",
"bookid" : booktarget.pk,
"multimediaurl" : multimediaused.url
}
result = push_service.notify_single_device(registration_id=registration_id, data_message=data_message)
Everything inside this code is working, because I get them correctly on Android. But on iOS... I can't get it working.
I have get the notifications token, I have post it to my server, I have use the notification sender on FCM console to send test push notifications (the iPhone get them), but not the ones from my custom method, It doesn't show anything. Is anything wrong in the server method or am I missing something?
This is the swift code:
import UIKit
import KeychainSwift
import Firebase
import FirebaseMessaging
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
var window : UIWindow?;
var storyboard : UIStoryboard?;
var token = ""
let gcmMessageIDKey = "gcm.message_id"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
self.storyboard = UIStoryboard(name: "Main", bundle: Bundle.main);
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.font: UIFont(name: "PT Sans", size: 12)!], for: .normal)
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.font: UIFont(name: "PT sans", size: 12)!], for: .selected)
let keychain = KeychainSwift()
token = keychain.get("token") ?? ""
if (token != ""){
print("log-token: ", token)
print("log-redirection: ", "no redirection needed!")
FirebaseApp.configure()
Messaging.messaging().delegate = self
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
} else {
print("log-token: ", "noToken")
print("log-redirection: ", "redirection to LoginController")
window?.rootViewController = self.storyboard?.instantiateViewController(withIdentifier: "loginView");
}
return true
}
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
postNotificationToken(token: token)
}
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
let dataDict:[String: String] = ["token": fcmToken]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
func postNotificationToken(token:String) {
var request = URLRequest(url: URL(string: "https://myurl?myparam="+token)!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Bearer "+self.token, forHTTPHeaderField: "myauth")
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
let httpURLResponse = response as? HTTPURLResponse;
if (httpURLResponse?.statusCode == 200){
let string = String.init(data: data!, encoding: String.Encoding.utf8)
print(string)
} else {
print(httpURLResponse?.statusCode)
}
})
task.resume()
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Received data message: \(remoteMessage.appData)")
}
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void)
{
completionHandler([.alert, .badge, .sound])
}
// MARK: UISceneSession Lifecycle
}
This are my target capabilities:
And this is my key for APN notifications in my developer account:
With FCM console, notifications are Ok:
Thanks for reading this long post. Anything will help!
Ok, I have it working mixing some of the answers and some code found on other posts. First of all, I am using APN key, not APN certificates.
Second, I'm checking what OS has the user to I have to send the notification (iOS/Android) so I can configure different notification structure. This is the notification system in python/django using PyFCM library and sending the iOS notification as alert, as I found on this post :
if devicetype == "and":
registration_id = profiletarget.device_token
message_title = "default-title"
message_body = "default-body"
data_message = {
"title" : "title",
"body" : "body",
"bookid" : booktarget.pk,
"multimediaurl" : multimediaused.url
}
result = push_service.notify_single_device(registration_id=registration_id, data_message=data_message)
else:
registration_id = profiletarget.device_token
message_title = "title"
message_body = "body"
data_message = {
"bookid" : booktarget.pk,
"multimediaurl" : multimediaused.url,
}
result = push_service.notify_single_device(registration_id=registration_id,
message_title=message_title,
message_body=message_body,
data_message=data_message,
extra_kwargs={"apns_push_type": "alert"}
)
In Xcode I only had to ad capabilities for push notifications and background mode - remote notifications, as posted in the question pic.
In code, I missed some part of firebase tutorial corresponding to this methods:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo["body"] {
print("Notif metod 1")
// gotoWritting(bookid: messageID)
}
// Print full message.
print("Notif metod 1")
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo["body"]{
print("Notif metod 2")
// gotoWritting(bookid: messageID)
}
// Print full message.
print(userInfo["bookid"]!)
gotoWritting(bookid: Int(userInfo["bookid"]! as! String) ?? 90)
completionHandler(UIBackgroundFetchResult.newData)
}
The second one is the one is getting triggered by the notification click (background, foreground and app closed...) and once its clicked, I can redirect the user with some notification params.
I cant test on previous version, but hope it works on iOS 9 to (If you know if that works or not, let me know please).
Thanks to everyone who helped!
Did you configured your app certificate with push notifications? 👇
Also you will need to configure the project in Xcode select one of your targets and go to -> SignIn and capabilities and add the Push Notifications capability for each target, the pushes ain't working in the simulator visible, but the method didReceiveRemoteNotification is triggered, you can debug with some log or breakpoint if you are receiving them.
Try to send this type of custom formate with custom payload
note : this is node.js code
let message = {
tokens: iosTokens,
notification: {
title: "title",
body: "",
},data = {
"title" : "¿Listo para escribir?",
"body" : "Ha llegado tu turno para escribir en el relato. Recuerda que tienes un minuto para aceptar tu turno y 3 para escribir.",
"bookid" : booktarget.pk
},apns : {
payload: {
aps: {
mutableContent: true,
contentAvailable: true,
category: "CustomSamplePush",
alert: {
launchImage: "imageURL.jpeg",
sound: "default"
}
}
}
}
};

Facebook chat bot sending same message multiple times (Python)

I am working on a facebook mini-chat bot and I am encountering a problem which consists on the bot to receive the same message over and over even though it has already answered the message.
it keeps receiving the same text from FB and replying to it over and over
def message_handler(request):
data = json.loads(request.body.decode('utf-8'))
if data and data['object'] == 'page':
for pageEntry in data['entry']:
print "nombre de message", len(pageEntry['messaging'])
for messagingEvent in pageEntry['messaging']:
if messagingEvent.get('optin'):
print "optin", messagingEvent
receivedAuthentication(messagingEvent)
elif messagingEvent.get('message'):
print "message", messagingEvent
receivedMessage(messagingEvent)
elif messagingEvent.get('delivery'):
print "delivery", messagingEvent
receivedDeliveryConfirmation(messagingEvent)
elif messagingEvent.get('postback'):
print "postback", messagingEvent
receivedPostback(messagingEvent)
else:
print "UnHandled"
return HttpResponse(status=200)
def receivedMessage(event):
senderID = event.get('sender').get('id')
message = event.get('message')
messageText = message.get('text')
messageAttachments = message.get('attachments')
if messageText:
if messageText == 'image':
sendImageMessage(senderID)
elif messageText == 'button':
sendButtonMessage(senderID)
elif messageText == 'generic':
sendGenericMessage(senderID)
elif messageText == 'receipt':
sendReceiptMessage(senderID)
elif messageText == 'hey':
sendTextMessage(senderID, "Get it. Gimme a moment to process it :). Will get back to you in a moment")
send_seen()
send_typing()
words = words_gen()
sendTextMessage(senderID, words)
def callSendAPI(messageData):
requests.post(
url='https://graph.facebook.com/v2.6/me/messages?access_token=' + config.page_token,
data=json.dumps(messageData),
headers={"Content-Type":"application/json"}
)
I get that I need to send a status 200 every time, which I did but still receiving the same text over and over
Here are the events I am subscribed to
conversations, message_deliveries, message_reads, messages, messaging_optins, messaging_postbacks, picture
I removed messaging_echoes because I thought it was the problem turned out to not
I have resolved this issue by writing a function and checking duplicate messages in my Web API service.
Here I am generating message unique id either by payload or message received from Facebook which user clicks or types and then comparing with earlier stored unique value from concurrent dictionary.
_messageUniqueKeysBySender is ConcurrentDictionary and I am caching values by Sender Id for 30 minutes.
private bool IsDuplicate(Messaging messaging)
{
var messageUniqueId = string.Empty;
var messageMessaging = messaging as MessageMessaging;
if (messageMessaging != null)
messageUniqueId = messageMessaging.Message.Id + messageMessaging.Message.SequenceNumber;
else if (messaging is PostbackMessaging)
messageUniqueId = ((PostbackMessaging)messaging).Postback.Payload +
((PostbackMessaging)messaging).TimestampUnix;
if (string.IsNullOrEmpty(messageUniqueId)) return false;
string existingUniqueId;
if (_messageUniqueKeysBySender.TryGetValue(messaging.Sender.Id, out existingUniqueId))
{
if (existingUniqueId == messageUniqueId)
{
return true;
}
else
{
_messageUniqueKeysBySender.TryUpdate(messaging.Sender.Id, messageUniqueId, existingUniqueId);
return false;
}
}
_messageUniqueKeysBySender.TryAdd(messaging.Sender.Id, messageUniqueId);
return false;
}
And then by checking in main code
try
{
if (!IsDuplicate(messaging))
{
var conversation = _conversationRepository[messaging.Sender.Id] ?? new Conversation(messaging.Sender.Id);
message = await _bot.RespondToMessagingAsync(conversation, messaging);
_conversationRepository[messaging.Sender.Id] = conversation;
_logger.ForContext("FacebookMessage", messagingJson).LogDuration("Processing Facebook message", sw);
}
else
_logger.ForContext("FacebookMessage", messagingJson).Warning("Duplicate message skipped");
}
catch (Exception ex)
{
_logger.ForContext("FacebookMessage", messagingJson).Error(ex, "Failed to process message");
message = new TextMessage(Resources.Error);
hasError = true;
}

Categories

Resources