Has anyone created an open source project that exposes the facebook messenger bot API in java? (or another language I could convert?)
Essentially an object hierarchy for the stack found in:
https://developers.facebook.com/docs/messenger-platform/send-api-reference
I'd rather not just use JsonObjects, etc. nor Maps to extract the incoming JSON chat messages or to build the outgoing structured chat replies. If an open source project for this exists -- I have not found it.
Take a look at FaceBot. The goal of FaceBot is making the Facebook's Messenger Platform easier: with FaceBot, you only need less than 5 lines of code to set up your own Messenger bot.
Here's an example:
public class MyFaceBotBehavior extends AbstractFaceBot {
public void defineBehavior() {
// Setting my tokens from Facebook (page token and validation token for webhook).
FaceBotContext.getInstance().setup("myFacebookPageToken", "myFacebookWebhookValidationToken");
// Defining a bot which will reply with "Hello World!" as soon as I write "Hi"
addActionFrame(new MessageEvent("Hi"),
new MessageAutoReply("Hello World!"));
}
}
If you have questions or need help, feel free to contact me (I'm the developer).
With the open source project messenger4j you will get all you need.
It's an easy to use Java library for building chatbots on the Messenger Platform.
It provides a rich builder API to construct the outgoing messages.
Furthermore it parses the inbound messages to specific java objects and automatically detects their type. For each message type or event you can register corresponding event handlers.
Receiving:
String payload = ... // callback request body
String signature = ... // 'X-Hub-Signature' request header
// JDK 8 version
MessengerReceiveClient receiveClient = MessengerPlatform.newReceiveClientBuilder("APP_SECRET", "VERIFICATION_TOKEN")
.onTextMessageEvent(event -> System.out.printf("%s: %s", event.getSender().getId(), event.getText()))
.build();
// JDK 7 version
MessengerReceiveClient receiveClient = MessengerPlatform.newReceiveClientBuilder("APP_SECRET", "VERIFICATION_TOKEN")
.onTextMessageEvent(new TextMessageEventHandler() {
#Override
public void handle(TextMessageEvent event) {
System.out.printf("%s: %s", event.getSender().getId(), event.getText());
}
})
.build();
receiveClient.processCallbackPayload(payload, signature);
Sending (simple):
MessengerSendClient sendClient = MessengerPlatform.newSendClientBuilder("PAGE_ACCESS_TOKEN").build();
sendClient.sendTextMessage("RECIPIENT_ID", "Hi there, how are you today?");
Sending (complex):
ReceiptTemplate receipt = ReceiptTemplate.newBuilder("Stephane Crozatier", "12345678902", "USD", "Visa 2345")
.orderUrl("http://petersapparel.parseapp.com/order?order_id=123456")
.timestamp(1428444852L)
.addElements()
.addElement("Classic White T-Shirt", 50F)
.subtitle("100% Soft and Luxurious Cotton")
.quantity(2)
.currency("USD")
.imageUrl("http://petersapparel.parseapp.com/img/whiteshirt.png")
.toList()
.addElement("Classic Gray T-Shirt", 25F)
.subtitle("100% Soft and Luxurious Cotton")
.quantity(1)
.currency("USD")
.imageUrl("http://petersapparel.parseapp.com/img/grayshirt.png")
.toList()
.done()
.addAddress("1 Hacker Way", "Menlo Park", "94025", "CA", "US").street2("").done()
.addSummary(56.14F).subtotal(75.00F).shippingCost(4.95F).totalTax(6.19F).done()
.addAdjustments()
.addAdjustment()
.name("New Customer Discount")
.amount(20.00F)
.toList()
.addAdjustment()
.name("$10 Off Coupon")
.amount(10.00F)
.toList()
.done()
.build();
sendClient.sendTemplate("RECIPIENT_ID", receipt);
BTW: I've built it.
I am currently working on a bot framework in java called JBot and the fb portion is currently under development but the Slack part is done and is used by several developers already.
Related
In my current Java project, it's easy to track server-side user events in the "old" Google Analytics Universal Project with simple REST calls to Google Analytics. So that location tracking was working, i could override the server ip with the user ip, according to the parameter "&uip=1.2.3.4" (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters?hl=de#uip).
As upgrading to GA4 is recommended, I was able to change all the REST parameters in my project and show my events in the new dashboard, except for the user location. I can't find any information about such a parameter. I tried using still "uip" but now all my requests are located to the country of my server.
Unfortunately it's not possible to track the event client side, because my project is a simple REST API, returning only JSON data.
Does anyone have an idea, if there's such a parameter like "uip" for ga4 or if this isn't possible anymore?
In the following way I setup my parameters:
private String getQueryParameters(MeasurementEvent event) {
StringBuilder body = new StringBuilder();
body.append("?v=").append(version);
body.append("&tid=").append(trackingId);
body.append("&cid=").append(event.getClientId());
body.append("&en=").append(eventName);
body.append("&aip=1");
if (StringUtils.hasText(event.getAction())) {
body.append("&ep.useraction=").append(event.getAction());
}
if (StringUtils.hasText(event.getCategory())) {
body.append("&ep.awsregion=").append(event.getCategory());
}
if (StringUtils.hasText(event.getLabel())) {
body.append("&ep.softwarename=").append(event.getLabel());
}
if (StringUtils.hasText(event.getRemoteAddress())) {
body.append("&uip=").append(event.getRemoteAddress());
}
if (StringUtils.hasText(event.getUrl())) {
body.append("&dl=").append(event.getUrl());
}
return body.toString();
}
i do not get any notification from firebase but when i test with Pusher app i get the notification.
these are my steps i have Done. help me if i have done something wrong.
1_ add notificationService as below.
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: #escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
// Modify the notification content here...
bestAttemptContent.title = "hello"
bestAttemptContent.body = "this is test"
contentHandler(bestAttemptContent)
}
}
}
2 _ set notificationCenter delegate to self in app delegate
Messaging.messaging().delegate=self
UNUserNotificationCenter.current().delegate = self
3_ device token for sending notification (i store this to server)
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.
}
i send this FCMToken to server Side(java,spring boot)
4_ i have enabled push notification in Capabilities
5_ i have added .p12 file in cloud messaging of project settings in firebase console but i have big question for this !???? should i login to firebase with my server's account ? or make an account for my self ?? because i have created one for my self.
some tips :
we are a team like server side(JAVA). web , android and ios
which this push notification is working on android but not on ios.
i think i'm doing something in a wrong way.
thank you for reading this topic and helping me out.
Here is the steps to cross check your issue,
Notification Capabilities has to be enabled.
Certificate you created on apple member center should enable the push
notification
In firebase console go to settings -> project settings -> cloud messaging -> check the server key
This key and the key what you gave to you server team should be same
Check APNs Authentication Key or APNs Certificates added or not.
If you are using APNs Certificates, that should be same that you generated in the appId in the member center
get the fcm token from the xcode console -> go to firebase console -> grow -> cloud messaging -> new notification
-> and try test on device. if you receive notification client side (device) has no issues. if not server side has to double check the server key.
Add your googleServiceInfo.plist to your project. add the reversed key in your app info.
in Appdelegate, configure your firebase
FirebaseApp.configure()
Update, As per your question in the comment, am updating this question.
To make use of NotificationService Extension, you notification must include mutable-content property in the notification payload. using fcm api you can do that. put these in the post man,
https://fcm.googleapis.com/fcm/send
in the headers, add your server key (you can get this from your firebase console)
in the body add this payload to fire notification. this will trigger your Notification Service Extension.
{
"notification": {
"title": "1",
"body": "",
"click_action": "",
"icon": "",
"mutable_content": true,
"content_available": true
},
"registration_ids":["add your fcm token"],
"data": {}
}
As per the tutorial:
https://code.tutsplus.com/tutorials/ios-10-notification-service-extensions--cms-27550
I am currently working on Agora.io services which give us
audio,video,one-to-one and broadcast communication
I have successfully implemented these with the help of there given samples, and successfully add signalling module.
Problem is that signalling call must be active to access all features of it now I want to access all features of signalling at the time when app is closed like whatsapp and other these type of application one solution is make a service of signalling class but this is not professional solution.
I want efficient one solution
This cannot be done with any 3rd party APIs. This is a system level functionality offered by Apple & Google. You will have to use CallKit (for iOS) or ConnectionService (for Android) to achieve this functionality.
I have done exactly the same thing a few days ago.
For iOS, you have use PushKit and CallKit in the following ways:-
.1. Enable background mode and also check voip.
Import Pushkit and implement PKPushRegistryDelegate functions.
Register pushkit like this :-
func registerPushkitToken() -> Void {
pushRegistry = PKPushRegistry.init(queue: DispatchQueue.main)
pushRegistry?.delegate = self
pushRegistry?.desiredPushTypes = [.voIP]
}
3.Implement the token fuction
func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials:
PKPushCredentials, for type: PKPushType) {
let tokenChars = pushCredentials.token.hexString()
}
Implement the following function for parsing notification
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
if let userInfo = payload.dictionaryPayload["userInfo"] as? [AnyHashable:Any]{
}
}
Implement provider delegate functions:
let providerConfiguration = CXProviderConfiguration(localizedName: appName)
providerConfiguration.supportsVideo = true
providerConfiguration.maximumCallsPerCallGroup = 1
providerConfiguration.maximumCallGroups = 1
providerConfiguration.supportedHandleTypes = [.generic]
Implement CXProviderDelegate functions
func providerDidReset(_ provider: CXProvider) {
print("Function: \(#function), line: \(#line)")
sessionPool.removeAll()
}
func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
print("Function: \(#function), line: \(#line)")
guard let session = pairedSession(of:action.callUUID) else {
action.fail()
return
}
let callUpdate = CXCallUpdate()
callUpdate.remoteHandle = action.handle
callUpdate.hasVideo = true
callUpdate.localizedCallerName = callDetails.dispalyName;
callUpdate.supportsDTMF = false
provider.reportCall(with: action.callUUID, updated: callUpdate)
delegate?.callCenter(self, startCall: session)
action.fulfill()
}
You can also refer to my post here. how to integrate Callkit with Agora VOiP in swift 4 iOS?
I'm trying to find out how to push proper notifications using Codename One servers. I'd like to send notifications which basically look like LocalNotifications - with title, body, badge etc.
However in the documentation for push servers there seems to be just one field concerning the notification payload:
body - the body of the message.
Q1: How to push(server side through Codename One server) and display(Codename One app) a notification with title and body from the server?
I'd like be able to send and receive custom data in the payload too, e.g. reference to some app content which should be opened in the app when opening the app "from" that particular push notification.
Q2: Can I send basically anything as a notification body, even my own JSON?
In the Codename One API there is this callback interface PushCallback, specifically method void push(String value). Is this callback intended exactly for the purpose of "pre-processing/parsing" of the notification payload just before displaying it as a LocalNotification?
Thanks.
There are various types of push messages you can send in Codename One, namely 0,1,2,3,4,5,100, and 101.
If you require the title and the body, set your push type to 4 and separate your title and body with ; in your payload.
If you require a push with some hidden content which you can use to manipulate your app in the background, go for push type 3. Separate the visible and hidden payloads with ;. The hidden section is where you put your JSON string, just ensure the vissible message doesn't start with { or [. A php payload example will look something like this:
$vissibleMsg = "Cum ut quia delectus libero hic.";
$jsonString = json_encode(array("action" => "openMainForm", "id" => "1", "message" => $vissibleMsg));
$payload = $vissibleMsg . ";" . $jsonString;
And in your push(String value), read the hidden JSON content like this:
#Override
public void push(String value) {
Display.getInstance().callSerially(() -> {
if (value.startsWith("{") || value.startsWith("[")) {
try {
JSONObject response = new JSONObject(value);
switch (response.getString("action")) {
case "openMainForm":
//do whatever you want here
break;
default:
//perform default action here
break;
}
} catch (JSONException err) {
Log.e(err);
}
}
});
}
If you require a hidden content and a visible content with title and body, then you will have to send the push twice using type 2 and type 4 respectively, based on the link I shared above.
I am thinking about keeping all registration ids(push token) in DB and sending notifications to user from iPhone. I tried something like this but did not get any notification.
func sendPNMessage() {
FIRMessaging.messaging().sendMessage(
["body": "hey"],
to: TOKEN_ID,
withMessageID: "1",
timeToLive: 108)
}
What I am doing wrong or maybe it is impossible at all?
Currently it's not possible to send messages from the application itself.
You can send messages from the Firebase Web Console, or from a custom server using the server-side APIs.
What you might want to do is to contact a server (like via http call) and that server will send the message to the user.
This way ensure that the API-KEY of the server is protected.
PS: the sendMessage(..) api is called upstream feature, and can be used to send messages from your app to your server, if you server has an XMPP connection with the FCM server.
Yes you can send push notification through Firebase.Please make sure do NOT include the server-key into your client. There are ways "for not so great people" to find it and do stuff... The Proper way to achieve that is for your client to instruct your app-server to send the notification.
You have to send a HTTP-Post to the Google-API-Endpoint.
You need the following headers:
Content-Type: application/json
Authorization: key={your_server_key}
You can obtain your server key within in the Firebase-Project.
HTTP-Post-Content: Sample
{
"notification": {
"title": "Notification Title",
"text": "The Text of the notification."
},
"project_id": "<your firebase-project-id",
"to":"the specific client-device-id"
}
Google Cloud Functions make it now possible send push notifications from device-to-device without an app server.
From the Google Cloud Functions documentation:
Developers can use Cloud Functions to keep users engaged and up to
date with relevant information about an app. Consider, for example, an
app that allows users to follow one another's activities in the app.
In such an app, a function triggered by Realtime Database writes to
store new followers could create Firebase Cloud Messaging (FCM)
notifications to let the appropriate users know that they have gained
new followers.
Example:
The function triggers on writes to the Realtime Database path where followers are stored.
The function composes a message to send via FCM.
FCM sends the notification message to the user's device.
Here is a demo project for sending device-to-device push notifications with Firebase and Google Cloud Functions.
Diego's answer is very accurate but there's also cloud functions from firebase it's very convenient to send notifications in every change in the db. For example let's say you're building chat application and sending notification in every new follower change.
This function sample is very good example.
For more information about cloud functions you can check official docs.
I have an app that has a "send feedback to developer" section. I also have a User collection in my firestore database. When a user logs into the app, I have that Users data update their FCM token with the following code in my SceneDelegate.swift:
import Firebase
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
authListener = Auth.auth().addStateDidChangeListener({ (auth, user) in
Auth.auth().removeStateDidChangeListener(self.authListener!)
if user != nil {
DispatchQueue.main.async {
let docRef = Firestore.firestore().collection("User").document((user?.email)!)
docRef.getDocument { (snapshot, error) in
guard let snapshot = snapshot else {return}
Messaging.messaging().token { token, error in
if let error = error {
print("Error fetching FCM registration token: \(error)")
} else if let token = token {
docRef.updateData(["FCMtoken":token])
print("FCM registration token: \(token)")
}
}
}
}
}
})
guard let _ = (scene as? UIWindowScene) else { return }
}
then in my feedback view controller i have this code to send my specific device (but you can look up/fetch which specific device you want in your database where the FCMtoken is stored where i have INSERT-DEVICE-TOKEN-HERE). The url to send to is "https://fcm.googleapis.com/fcm/send" and you can find YOUR-APP-FCM-KEY by going to your project settings in firebase, going to cloud messaging tab and its the server key.
func sendMePushNotification() {
let token = "INSERT-DEVICE-TOKEN-HERE"
if let url = URL(string: "https://fcm.googleapis.com/fcm/send") {
var request = URLRequest(url: url)
request.allHTTPHeaderFields = ["Content-Type":"application/json", "Authorization":"key=YOUR-APP-FCM-KEY"]
request.httpMethod = "POST"
request.httpBody = "{\"to\":\"\(token)\",\"notification\":{\"title\":\"Feedback Sent!\",\"body\":\"\(self.feedbackBox.text!)\",\"sound\":\"default\",\"badge\":\"1\"},\"data\": {\"customDataKey\": \"customDataValue\"}}".data(using: .utf8)
URLSession.shared.dataTask(with: request) { (data, urlresponse, error) in
if error != nil {
print("error")
} else {
print("Successfully sent!.....")
}
}.resume()
}
}
Use onesignal,you can send device to notifications or device to segments ,it can work with firebase in this way
Use onesignal functions to create a specific id,save it in a firebase database ,then when the id can be put in another function that is used to send a notification
Notes: 1-i am using it in my apps with firebase works perfectly
2-i can submit that code,just someone comments so i can find this answer