Twilio programmable chat message user friendlyName - react-native

I am using Twilio Programmable Chat to add a chat feature to my mobile app built in React Native. I'm using the JS client SDK for this.
When the app receives a new message, the data that comes through uses the user identity for the author field. Is there away to include the friendlyName in the payload so I can display this to the user.
I could make a separate request for all users and find the correct user within the app but it would be great if this data could just be on the same request.
Thanks for any help

Yes, only author field present in new message event, I used an alternate approach
channelMembersDict = {}
// Assuming you have set selected an Channel
this.activeChannel.getMembers().then(members => {
members.forEach(mem => {
//member contains friendlyName attribute
this.channelMembersDict[mem.state.identity] = mem;
//If you really want user then
mem.getUser().then(user => {
this.channelMembersDict[mem.state.identity] = user;
});
});

Related

Task Module call from Ms Teams in Bot Framework

I am looking to open a task module (Pop up - iframe with audio/video) in my bot that is connected to Teams channel. I am having issues following the sample code provided on the GitHub page.
I have tried to follow the sample and incorporate to my code by did not succeed.
In my bot.cs file I am creating card action of invoke type:
card.Buttons.Add(new CardAction("invoke", TaskModuleUIConstants.YouTube.ButtonTitle, null,null,null,
new Teams.Samples.TaskModule.Web.Models.BotFrameworkCardValue<string>()
{
Data = TaskModuleUIConstants.YouTube.Id
}));
In my BotController.cs that inherits from Controller
[HttpPost]
public async Task PostAsync()
{
// Delegate the processing of the HTTP POST to the adapter.
// The adapter will invoke the bot.
await _adapter.ProcessAsync(Request, Response, _bot);
}
public async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
if (activity.Type == ActivityTypes.Invoke)
{
return HandleInvokeMessages(activity);
}
return new HttpResponseMessage(HttpStatusCode.Accepted);
}
private HttpResponseMessage HandleInvokeMessages (Activity activity)
{
var activityValue = activity.Value.ToString();
if (activity.Name == "task/fetch")
{
var action = Newtonsoft.Json.JsonConvert.DeserializeObject<Teams.Samples.TaskModule.Web.Models.BotFrameworkCardValue<string>>(activityValue);
Teams.Samples.TaskModule.Web.Models.TaskInfo taskInfo = GetTaskInfo(action.Data);
Teams.Samples.TaskModule.Web.Models.TaskEnvelope taskEnvelope = new Teams.Samples.TaskModule.Web.Models.TaskEnvelope
{
Task = new Teams.Samples.TaskModule.Web.Models.Task()
{
Type = Teams.Samples.TaskModule.Web.Models.TaskType.Continue,
TaskInfo = taskInfo
}
};
return msg;
}
return new HttpResponseMessage(HttpStatusCode.Accepted);
}
There is more code as per the GitHub sample but I won't paste it here. Can someone point me into the correct direction ?
I have got to the stage that it is displaying a pop up window but the content and title comes from manifest file instead of creating actual iframe also no video is rendering. My goal is to render video within my teams using iframe container.
The important part from the sample:
This sample is deployed on Microsoft Azure and you can try it yourself by uploading Task Module CSharp.zip to one of your teams and/or as a personal app. (Sideloading must be enabled for your tenant; see step 6 here.) The app is running on the free Azure tier, so it may take a while to load if you haven't used it recently and it goes back to sleep quickly if it's not being used, but once it's loaded it's pretty snappy.
So,
Your Teams Admin MUST enable sideloading
Your bot MUST be sideloaded into Teams
The easiest way to do this would be download the sample manifest, open it in App Studio, then edit your bot information in. You then need to make sure Domains and permissions > Valid Domains are set for your bot. Also ensure you change the Tabs URLs to your own.
You also need to make sure that in your Tasks, the URLs they call ALL use https and not http. If anywhere in the chain is using http (like if you're using ngrok and http://localhost), it won't work.

How to use FaceID using Xamarin.forms?

What I need to implement that Face ID authentication will work on Xamarin.forms project?
You have to do this natively on your iOS project, and then expose it to your Forms project using a DependencyService or some kind of ioc.
You must add to your info.plist the NSFaceIDUsageDescription key, otherwise the app will crash when asking for authentication.
Here is a snippet that authenticates a user locally:
var context = new LAContext();
LAContextReplyHandler replyHandler;
NSError AuthError;
if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out AuthError))
{
replyHandler = new LAContextReplyHandler((success, error) =>
{
// Handle authentication success or error
});
// Authenticate and ask for permission if needed.
context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, "Authenticate", replyHandler);
}

Sending a link using push notifications in Azure for Android

I have created a backed in asp.net web-forms successful send a notification for all registered devices but I tired to send a link for example I need to send one push notification include a link When user touch on the notification redirect to mobile browser and open the link.
private static async void SendNotificationAsync()
{
NotificationHubClient hub = NotificationHubClient
.CreateClientFromConnectionString("<Here is my endpoint >", "<hub name>");
await hub.SendGcmNativeNotificationAsync("{ \"data\" : {\"message\":\"Hello Users \"}}");
}
Based on my experience, we could use custom json format and at receiver end convert that string into url. For example,Here’s a sample of the complete JSON payload with a custom "web_link" key containing the URL:
{"data": "{\"message\":\"xxxx\",\"web_link\":\"https://www.example.com\"}"}
Then we could override the OnMessage function to create Notification, we also could get more detail info from the Azure document.

How to pass Firebase Auth Token from client to server?

The website that I'm working on uses Firebase authentication and different users that login have different permissions as to which pages they can visit.
The way signing in is setup is similar to this post:
User Logins in with two parameters - "id" and "email"
Server uses these to create a custom "uid", then uses the Firebase Admin SDK to create a custom token that is sent back to the client.
The client logs in with the Javascript Firebase SDK - firebase.auth().signInWithCustomToken()
Now that the user is logged in, they can click different pages - i.e. '/foo', '/bar'
The issue I'm running into is that when they visit new pages, I'm trying to pass the token from the client back to the server (almost identical to how its done in this Firebase Doc ), verify the token & check if it has permission to view the webpage.
I'm trying to figure out the best (& most secure) way to do this. I've considered the following option:
Construct a URL with the token, but I've heard this isn't good practice because the token is getting exposed and session hijacking becomes a lot easier.
I've been trying to pass the token in the request header, but from my understanding you can't add headers when the user clicks on a link to a different page (or if its redirected in javascript). The same issue applies to using POST.
What can I do to securely pass this information to the server and check permissions when a user clicks on a link to a different page?
You can get the accessToken (idToken) on client side by:
var accessToken = null;
firebase.auth().currentUser
.getIdToken()
.then(function (token) {
accessToken = token;
});
and pass it in your request headers:
request.headers['Authorization'] = 'Bearer ' + accessToken;
and on your server side get the token with your prefered method and authenticate the request with Firebase Admin SDK, like (Node.js):
firebaseAdmin.auth()
.verifyIdToken(accessToken)
.then(decodedIdToken => {
return firebaseAdmin.auth().getUser(decodedIdToken.uid);
})
.then(user => {
// Do whatever you want with the user.
});
Nowadays, it looks like we're meant to use httpsCallable() client-side to get an object pre-authorized to talk to your endpoint.
eg:
// # ./functions/index.js
exports.yourFunc = functions.https.onCall((data, context) => {
// Checking that the user is authenticated.
if (!context.auth) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
'while authenticated.');
}
// ... rest of your method
});
// ./src/models/addMessage.js
const firebase = require("firebase");
require("firebase/functions");
firebase.initializeApp({
apiKey: '### FIREBASE API KEY ###',
authDomain: '### FIREBASE AUTH DOMAIN ###',
projectId: '### CLOUD FUNCTIONS PROJECT ID ###'
databaseURL: 'https://### YOUR DATABASE NAME ###.firebaseio.com',
});
var functions = firebase.functions();
// This is the new code:
var yourFunc = firebase.functions().httpsCallable('yourFunc');
yourFunc({foo: bar}).then(function(result) {
// ...
});
From firebase documentation

Prevent getting old updates from Telegram Bot API using a web hook

I'm writing a Telegram bot and I'm using the official bot API. I've got a webhook server that handles requests and sends a 200 OK response for every request.
Before the server stops, the webhook is detached so Telegram does not send updates anymore. However, whenever I turn the bot on and set the webhook URL again, Telegram starts flooding the webhook server with old updates.
Is there any way I can prevent this without requesting /getUpdates repeatedly until I reach the last update?
Here's a heavily simplified version of how my code looks like:
var http = require('http'),
unirest = require('unirest'),
token = '***';
// Attach the webhook
unirest.post('https://api.telegram.org/bot' + token + '/setWebhook')
.field('url', 'https://example.com/api/update')
.end();
process.on('exit', function() {
// Detach the webhook
unirest.post('https://api.telegram.org/bot' + token + '/setWebhook')
.field('url', '')
.end();
});
// Handle requests
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' })
res.end('Thanks!');
});
server.listen(80);
Thanks in advance.
The best way is to use update_id which is a specific number that increases on every new request (i.e. update). How to implement it?
First off, let's start with the following anonymous class (using PHP7):
$lastUpdateId = new class()
{
const FILE_PATH = "last-update-id.txt";
private $value = 1;
public function __construct()
{
$this->ensureFileExists();
$this->value = filesize(self::FILE_PATH) == 0
? 0 : (int)(file_get_contents(self::FILE_PATH));
}
public function set(int $lastUpdateId)
{
$this->ensureFileExists();
file_put_contents(self::FILE_PATH, $lastUpdateId);
$this->value = $lastUpdateId;
}
public function get(): int
{
return $this->value;
}
public function isNewRequest(int $updateId): bool
{
return $updateId > $this->value;
}
private function ensureFileExists()
{
if (!file_exists(self::FILE_PATH)) {
touch(self::FILE_PATH);
}
}
};
What the class does is clear: Handling the last update_id via a plain file.
Note: The class is tried to be as short as possible. It does not provide error-checking. Use your custom implementation (e.g. use SplFileObject instead of file_{get|put}_contents() functions) instead.
Now, there are two methods of getting updates: Long Polling xor WebHooks (check Telegram bot API for more details on each methods and all JSON properties). The above code (or similar) should be used in both cases.
Note: Currently, it is impossible to use both methods at the same time.
Long Polling Method (default)
This way, you send HTTPS requests to Telegram bot API, and you'd get updates as response in a JSON-formatted object. So, the following work can be done to get new updates (API, why using offset):
$botToken = "<token>";
$updates = json_decode(file_get_contents("https://api.telegram.org/bot{$botToken}/getUpdates?offset={$lastUpdateId->get()}"), true);
// Split updates from each other in $updates
// It is considered that one sample update is stored in $update
// See the section below
parseUpdate($update);
WebHook Method (preferred)
Requiring support for HTTPS POST method from your server, the best way of getting updates at-the-moment.
Initially, you must enable WebHooks for your bot, using the following request (more details):
https://api.telegram.org/bot<token>/setWebhook?url=<file>
Replace <token> with you bot token, and <file> with the address of your file which is going to accept new requests. Again, it must be HTTPS.
OK, the last step is creating your file at the specified URL:
// The update is sent
$update = $_POST;
// See the section below
parseUpdate($update);
From now, all requests and updates your bot will be directly sent to the file.
Implementation of parseUpdate()
Its implementation is totally up to you. However, to show how to use the class above in the implementation, this is a sample and short implementation for it:
function parseUpdate($update)
{
// Validate $update, first
// Actually, you should have a validation class for it
// Here, we suppose that: $update["update_id"] !== null
if ($lastUpdateId->isNewRequest($update["update_id"])) {
$lastUpdateId->set($update["update_id"]);
// New request, go on
} else {
// Old request (or possible file error)
// You may throw exceptions here
}
}
Enjoy!
Edit: Thanks to #Amir for suggesting editions made this answer more complete and useful.
When you server starts up you can record the timestamp and then use this to compare against incoming message date values. If the date is >= the timestamp when you started...the message is ok to be processed.
I am not sure if there is a way you can tell Telegram you are only interested in new updates, their retry mechanism is a feature so that messages aren't missed...even if your bot is offline.
In the webhook mode, Telegram servers send updates every minute until receives an OK response from the webhook program.
so I recommend these steps:
Check your webhook program that you specified its address as url parameter of the setWebhook method. Call its address in a browser. It does not produce an output to view, but clears that probably there is no error in your program.
Include a command that produces a '200 OK Status' header output in your program to assure that the program sends this header to the Telegram server.
I have the same issue, then I tried to reset the default webhook with
https://api.telegram.org/bot[mybotuniqueID]/setWebhook?url=
after that, i verified the current getUpdates query were the same old updates but I sent new requests through the telegram's bot chat
https://api.telegram.org/bot[mybotuniqueID]/getUpdates
when I set up my webhook again the webhook read the same old updates. Maybe the getUpdates method is not refreshing the JSON content.
NOTE:
in my case, it was working fine until I decided to change /set privacy bot settings from botfather