I am creating a Telegram bot and need to x-callback to another application.
This is my x-callback that opens VLC and streams a video. It works fine when I use it in Siri Shortcuts or in Safari. But I need it to work on Telegram chat conversation.
vlc-x-callback://x-callback-url/stream?url=https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4
When I send it as raw text it obviously doesn't recognize it as a valid url and does nothing.
I have tried to format it Markdown, MarkdownV2 and HTML styles but none works.
I've also tried InlineKeyboardButton giving it the text and url but it throws a BadRequest error
telegram.error.BadRequest: Inline keyboard button url is invalid
Is there any workaround to x-callback from Telegram to another app?
My question is implementation independent, but here is my code using python-telegram-bot
from telegram import Update, ParseMode, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import CommandHandler, CallbackContext, Updater
my_x_callback = 'vlc-x-callback://x-callback-url/stream?url=https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4'
def test(update: Update, context: CallbackContext):
update.message.reply_text(my_x_callback)
update.message.reply_text(f'[Play it on VLC]({my_x_callback})', parse_mode=ParseMode.MARKDOWN)
update.message.reply_text(f'[Play it on VLC]({my_x_callback})', parse_mode=ParseMode.MARKDOWN_V2)
update.message.reply_text(f'Play it on VLC', parse_mode=ParseMode.HTML)
button = InlineKeyboardButton('Play it on VLC', url=my_x_callback)
update.message.reply_text(
'Testing InlineKeyboard',
reply_markup=InlineKeyboardMarkup([[button]])
)
if __name__ == '__main__':
updater = Updater('TOKEN')
updater.dispatcher.add_handler(CommandHandler('test', test))
updater.start_polling()
updater.idle()
I had a similar use case once where I wanted to use mailto: links. My workaround is to create a website URL that points to the mailto: link. I.e. flow is:
Generate mailto link depending on users request
Generate https:// url that points to the link - in my case that's done via a self-hosted YOURLS instance
used that generated URL either for an inline buttton or as text link.
Related
I have the Webchat (from the Microsoft Bot Framework) running embedded in another application that uses a browser under the hood.
When trying to add Authentication to the bot, I realized that the OAuthCard's Sign-in button doesn't work because is trying to open a blank window (about:blank) that is used to redirect the user to the login page of the identity provider. In the embedded context, the OS doesn't know how to handle the about:blank call. See the image below.
I'm following this example, that it is actually working on the browser:
Add authentication to a bot
Bot authentication example
I want to know if there is a way to change the behavior of the "Sign In" button of the OAuthCard to just open the sign-in URI directly without using the about:blank and redirect technique.
I was able to make it work after finding out that was possible to change the button type of the OAuthCard from "signin" to "openUrl" before the Webchat does the rendering.
There seems to exist a similar issue with Microsoft Teams. Here where I found the clue:
https://github.com/microsoft/botframework-sdk/issues/4768
According to the Webchat reference, it is possible to intersect and change the activities:
https://github.com/microsoft/BotFramework-WebChat/blob/master/docs/API.md#web-chat-api-reference
Here is the solution, that is more like a hack. I hope this would be configurable in the future:
// Change the button type in the OAuthCard to the type of OpenUrl
const store = window.WebChat.createStore( {}, ( { dispatch } ) => next => action => {
if (action.type == "DIRECT_LINE/QUEUE_INCOMING_ACTIVITY" &&
action.payload.activity.hasOwnProperty("attachments") &&
action.payload.activity.attachments[0].contentType === "application/vnd.microsoft.card.oauth") {
action.payload.activity.attachments[0].content.buttons[0].type = "openUrl";
}
return next( action );
});
// Pass the store to the webchat
window.WebChat.renderWebChat({
...,
store
});
I'm just dipping a toe in the water with Crystal at the moment and, as an exercise, trying to port one of my Python scripts across.
The script in question downloads the 'latest' PDF from a URL which takes the form: "http://somesite.com/download/latest/". When visited that URL automatically redirects to the page for the latest download eg. "http://somesite.com/download/4563/"
I'm having difficulty working out how to implement this in Crystal so that I can grab the actual URL that the redirect ends up on.
In Python I do:
currenturl = urllib.request.urlopen(latesturl)
#above will redirect to URL of format http://somesite.com/download/XXXXX/
#where XXXXX is the current d/load
endurl = currenturl.geturl()
...which gives me the end URL in the "endurl" variable.
But, reading the docs for Crystal's "http/client" I can't see any way to return the actual URL that a redirect ends up on. Is it possible?
Crystal's HTTP::Client currently can't automatically follow redirects.
Please note that you're reading an outdated version of the API docs, the current is at https://crystal-lang.org/api/latest/HTTP/Client.html (I don't think there have been relevant changes between 0.24.1 and 0.26.1 though).
But you can easily access the redirect URL from reading the Location header of an HTTP response:
response = HTTP::Client.get latesturl
endurl = response.headers["Location"]
I can't seem to get the embedded URL in a status, for example, in id=780804331608109057 -
https://twitter.com/i/web/status/780804331608109057
When I retrieve this via GET /statuses/:id, with include_entities set to true, the response looks like this:
"text":"Here\u2019s WSJ \"An Underwhelming Trump-Clinton Debate\u201d trying to spin this as something other than a Clinton triumph\u2026 https:\/\/t.co\/dpkmphGI8k",
"truncated":true,
"entities":
{"hashtags":[],"symbols":[],"user_mentions":[],"urls":
[{"url":"https:\/\/t.co\/dpkmphGI8k",
"expanded_url":"https:\/\/twitter.com\/i\/web\/status\/780804331608109057",
"display_url":"twitter.com\/i\/web\/status\/7\u2026","indices":[114,137]}]},
"source":"\u003ca href=\"https:\/\/about.twitter.com\/products\/tweetdeck\"rel=\"nofollow\"\u003eTweetDeck\u003c\/a\u003e",....
When viewed on my web client, the status instead displays the link to WSJ (referred through t.co) What I would like is one or both of these URLs to show up in my API response:
https://pbs.twimg.com/media/CtX5Sz8WIAAm4tq.jpg
what would be the short URL that looks like "t.co" followed by "/HJs4kbmTKz" (I have to break this up so SO doesn't complain.)
What am I doing wrong here?
The incredibly fast response from a staffer on the TwitterCommunity website was most gratifying:
You need to use tweet_mode=extended for the new longer Tweet format.
Ref: https://twittercommunity.com/t/missing-media-property-in-entities/70388/4
A search on this new parameter yields the appropriate documentation on dev.twitter.com - more documentation links on this mode probably exist out there. The most significant change appears to be that the key text is no longer used in non-compatibility mode - that's where the status text is, and unless you turn on compatibility mode, you have to now use the key full_text
https://dev.twitter.com/overview/api/upcoming-changes-to-tweets
I am trying to get the right redirection URL for my sharepoint documents which then I can use to open documents in WebView of iOS. Currently I am giving the absolute URL for the document where the doc is rendered inside WebView as PDF(Image/Readonly). Whereas I want to redirect to office webapp. Now my issue is I dont know if the URL for office web app is something which I can construct like appending /_layouts/15/WopiFrame.aspx?sourcedoc= or is the URL custom based on installations and we need to call some Sharepoint API which will let us know what is the base URL for Wopi service.
Currently I am passing URL like - https://.sharepoint.com/Shared%20Documents/demo/demo.docx
Whereas I want to pass URL like - https://.sharepoint.com/_layouts/15/WopiFrame.aspx?sourcedoc=/Shared%20Documents/demo/demo.docx
Looking forward for help.
Thanks in advance,
Vishwesh
File f = clientContext.Web.GetFileByServerRelativeUrl("/sites/ /Shared%20Documents/Title.docx");
clientContext.Load(f);
clientContext.ExecuteQuery();
ClientResult<String> result = f.ListItemAllFields.GetWOPIFrameUrl(SPWOPIFrameAction.Edit);
clientContext.Load(f.ListItemAllFields);
clientContext.ExecuteQuery();
result.Value contains a URL, something like this:
http://sharep.xxx:8080/sites/zxxx/_layouts/15/WopiFrame.aspx?sourcedoc=%2Fsites%2Fzxxx%2FShared%20Documents%2FTitle%2Edocx&action=edit
Also you can extract the extract Office Web Apps URL from the above page, if you don't want to hit the sharepoint at all.
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Utilities;
// Assume we have these variables:
// ctx: A valid client context
// serverRelativeUrl: the URL of the document
File f = ctx.Web.GetFileByServerRelativeUrl (serverRelativeUrl);
result = f.ListItemAllFields.GetWOPIFrameUrl(SPWOPIFrameAction.Edit);
ctx.Load(f.ListItemAllFields);
ctx.ExecuteQuery();
This builds on the answer from #thebitlic which was the silver bullet for sure! However he or she is doing two calls to the server. Through the wonders of CSOM batching, it's possible to do it in one round trip, and no need to bring back the File object at all.
Users open documents by links in old format http://server/db.nsf/VIEW_UNID/DOC_UNID. The form has property set to open XPage instead.
Origin of these links is email notification generated by "universal agent". It simply sends link to document. It does not know, what form is associated with what XPage, therefore it generates universal links instead of "/page.xsp&documentId=...".
The problem: relative links computed at client do not work - < a href = "/page.xsp?params"> should be more effective - no roundtrip and easy to compute at page load. They evaluate to http://server/db.nsf/0/page.xsp?params, what ends with Error 404, naturaly.
XPage contains "help" section, what is another document with RT field containing text, images and links. And relative links in that RT field work when XPage is opened from another XPage - view (/page.xsp), but fail when redirected from notification link (/0/UNID).
Question: How to effectively reset browser's address bar to extended XPages format http://server/db.nsf/page.xsp?documentId=DOC_UNID after opening redirected documents/views by old fashioned URLs?
Main problem is in discrepancy of relative links on server side (evaluated in SSJS) and client side (evaluated by browser). I have solved my problem by simple redirect in case document is open by old fashioned link.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:eventHandler event="onClientLoad" submit="false">
<xp:this.script><![CDATA[var url = "#{javascript:context.getUrl()}";
var l = window.location;
if (url != l) {
window.location.replace(url);
}
]]></xp:this.script>
</xp:eventHandler>
</xp:view>
Simply said, if open URL differs from internal URL (as resolved by XSP engine), browser redirects to correct URL. This solved many problems we had with inline images (image resource) and attachments.
Try "./page.xsp¶ms" or ../ if you want to go back to the root - I have noticed IBM do this in their coding as well. Hope this helps.
Have you tried to set pageBaseUrl property in your XPages? This would help to repair the relativ links:
<xp:this.pageBaseUrl>
<xp:baseUrl>
<xp:this.href><![CDATA[#{javascript:"http://stackoverflow.com/"}]]></xp:this.href>
</xp:baseUrl>
</xp:this.pageBaseUrl>
Another idea is to do a redirect in beforePageLoad-event in the XPage if the URL is in old fashioned style.