Lars Fosdal 1792 Posted October 16, 2020 https://larsfosdal.blog/2020/10/16/post-a-message-to-teams-from-delphi-using-webhooks/ 2 Share this post Link to post
Mahdi Safsafi 225 Posted October 16, 2020 Thanks Lars ! Just one small thing : the last URL that points to MS is invalid. Share this post Link to post
Lars Fosdal 1792 Posted October 16, 2020 Thanks, Mahdi! Fixed the URL. 1 Share this post Link to post
Anders Melander 1783 Posted October 16, 2020 Nice. I've been using the following to post the status of our Bamboo build jobs (it's a PowerShell script) but I've been thinking about adding Teams notification to some of our automated test tools and your example will come in handy there. $uri = 'https://outlook.office.com/webhook/yadayadayada/IncomingWebhook/yadayadayada/yadayadayada-yada-yada-yada-yadayadayada' if("${bamboo_buildFailed}" -eq "true"){ $status = 'Failure' }else { $status = 'Success' } $body = ConvertTo-Json -Depth 4 @{ title = 'FooBar Build Notification' text = "Build of FooBar version ${bamboo.fileVersion} completed with status $status" sections = @( @{ activityTitle = 'FooBar Build' activitySubtitle = '${bamboo.buildKey}' activityText = 'The build of ${bamboo.planRepository.branchName} ${bamboo.planRepository.revision} completed.' activityImage = 'https://pbs.twimg.com/profile_images/1128664840233525248/T3YNFtIt_400x400.png' }, @{ title = 'Details' facts = @( @{ name = 'Branch' value = '${bamboo.planRepository.branchName}' }, @{ name = 'Revision' value = '${bamboo.planRepository.revision}' } ) } ) potentialAction = @(@{ '@context' = 'http://schema.org' '@type' = 'ViewAction' name = 'Click here for details' target = @('${bamboo.buildResultsUrl}') }) } Invoke-RestMethod -uri $uri -Method Post -body $body -ContentType 'application/json' Share this post Link to post
Uwe Raabe 2057 Posted October 16, 2020 Nice! Any reason why you didn't make use of TRestClient instead of the Indy component? That would not only avoid the dependence on the OpenSSL libraries, but make it also work on other target platforms. unit O365WebHook; // Lars Fosdal, 2020 OCT 16 // Simple example without error handling interface uses System.Classes, System.SysUtils, REST.Json, REST.Client, REST.Types; type TWebHookMessage = class end; /// <summary> See https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using /// for examples of how to structure the json for creating advanced formats</summary> TSimpleText = class(TWebHookMessage) private FText: String; public property Text: String read FText write FText; constructor Create(const aText: string); end; type TWebHook = class private FClient: TRESTClient; FRequest: TCustomRESTRequest; FURL: string; protected property Client: TRESTClient read FClient; property Request: TCustomRESTRequest read FRequest; public constructor Create(const aURL: string = ''); destructor Destroy; override; function PostMessage(const aMsg: TWebhookMessage; aOwnsMsg: Boolean = False): Boolean; property URL: string read FURL write FURL; end; implementation { TWebHook } constructor TWebHook.Create(const aURL: string); begin inherited Create; FURL := aURL; FClient := TRESTClient.Create(nil); FRequest := TCustomRESTRequest.Create(nil); FRequest.Client := FClient; end; destructor TWebHook.Destroy; begin FRequest.Free; FClient.Free; inherited; end; function TWebHook.PostMessage(const aMsg: TWebhookMessage; aOwnsMsg: Boolean = False): Boolean; begin try Request.Client.BaseURL := URL; Request.Method := rmPOST; Request.AddBody(aMsg); Request.Execute; Result := Request.Response.Status.Success; finally if aOwnsMsg then aMsg.Free; end; end; { TSimpleText } constructor TSimpleText.Create(const aText: string); begin inherited Create; FText := aText; end; end. 2 Share this post Link to post
Lars Fosdal 1792 Posted October 17, 2020 @Anders Melander - We use Continua CI and FinalBuilder, and Continua has Teams support built in. My PS scripts also posts to Teams, but I use the PSTeams module. I still need to master how do PS Secure Vault secret keys across multiple users to avoid having the URLs in the PS script, though. Love your example of how simple it is to do Json in PowerShell! @Uwe Raabe Ignorance, I guess I've never used TRESTClient and I already was using Indy for JsonRPC. Thanks for sharing the modified version! I added it to the article. How TLS capable is the TRESTClient? Share this post Link to post
Lars Fosdal 1792 Posted October 17, 2020 Spotted one challenge with TRESTClient. No easy way to override the flags to ObjectToJsonString. Share this post Link to post
Uwe Raabe 2057 Posted October 17, 2020 2 hours ago, Lars Fosdal said: Spotted one challenge with TRESTClient. No easy way to override the flags to ObjectToJsonString. Thanks to the overloads for AddBody that is not a big challenge: { as Json string } Request.AddBody(TJSON.ObjectToJsonString(aMsg, [joIgnoreEmptyStrings, joIgnoreEmptyArrays, joDateIsUTC, joDateFormatISO8601])); { or as TJsonObject } Request.AddBody(TJSON.ObjectToJsonObject(aMsg, [joIgnoreEmptyStrings, joIgnoreEmptyArrays, joDateIsUTC, joDateFormatISO8601]), ooREST); 2 Share this post Link to post
Anders Melander 1783 Posted October 17, 2020 7 hours ago, Lars Fosdal said: Continua has Teams support built in. Yeah, well Bamboo being an Atlassian product relies on paid 3rd party add-ins for even the simplest things It does have support for XMPP but that isn't supported by Teams. Share this post Link to post
Vincent Parrett 750 Posted October 18, 2020 11 hours ago, Anders Melander said: Yeah, well Bamboo being an Atlassian product relies on paid 3rd party add-ins for even the simplest things Yes, this is true for all Atlassian products. We're moving away from Confluence because whilst it has support for producing documentation sites, it has no support for versioning.. unless you buy an expensive plugin - which totally takes over and makes a complete mess of things when you install on existing spaces, and and even worse mess (had to restore from backup) when uninstalling it. TBH, I fell out of love with confluence a long time ago.. we'll probably just switch to some sort of static site generator. They announced yesterday they are moving to cloud only and will retire the server/dc products over the next few years - that's just another reason to stop using their products imho. 1 Share this post Link to post
Anders Melander 1783 Posted October 18, 2020 14 hours ago, Vincent Parrett said: TBH, I fell out of love with confluence a long time ago.. we'll probably just switch to some sort of static site generator. I like it for internal documentation. For external use I think it sucks as you can't style it properly. If we were to replace it I would probably just use WordPress. 14 hours ago, Vincent Parrett said: They announced yesterday they are moving to cloud only and will retire the server/dc products over the next few years - that's just another reason to stop using their products imho. Oh... wow. I just read their announcement. For Jira, Confluence and Bitbucket this won't affect us much. Our Jira and Confluence are already on cloud. But for Bamboo this definitely means that we'll have to find alternatives and Bitbucket pipelines isn't a viable alternative. I just took their migration quiz. Bamboo isn't listed at all... and for Bitbucket it recommended that I migrate to Bitbucket Data Center - which is also being EOL'd.. Classic Atlassian. Share this post Link to post
Vincent Parrett 750 Posted October 18, 2020 Lots of unhappy Atlassian customers https://community.atlassian.com/t5/Atlassian-Cloud-Migration/To-all-Atlassian-server-champions-we-want-to-hear-from-you/qaq-p/1500873 And yes, it seems like Bamboo is just being quietly shelved, they don't mention it anywhere on their roadmaps or cloud migration pages. My guess is bitbucket piplelines is the intended migration path. I'll take this opportunity to offer a different migration option - https://www.finalbuilder.com/continua-ci - currently windows only, but we're working towards linux & mac support (agents first, server later). 1 Share this post Link to post
limelect 48 Posted October 19, 2020 (edited) @Lars Fosdal I used your blog https://larsfosdal.blog/2020/10/16/post-a-message-to-teams-from-delphi-using-webhooks/ to see what is all about I used D10.2.3. I got his error on create FClient := TRESTClient.Create(nil); P.S i used the updated section How to delete a post? Edited October 19, 2020 by limelect Share this post Link to post
Lars Fosdal 1792 Posted October 19, 2020 @limelect I removed the other post. I don't have 10.2 so I can't check if I see the same error. Did you get this error in a bare bone test project, or in a bigger project? Share this post Link to post
limelect 48 Posted October 19, 2020 (edited) @Lars Fosdal just copied O365WebHook.pas and procedure TestExampleToATeamsChannel; var Teams: TWebhook; begin Teams := TWebhook.Create('https://limelect.com'); try Teams.PostMessage(TSimpleText.Create('Hello from Delphi!')); finally Teams.Free; end; end; procedure TForm1.Button1Click(Sender: TObject); begin TestExampleToATeamsChannel; end; Using this post https://larsfosdal.blog/2020/10/16/post-a-message-to-teams-from-delphi-using-webhooks/ Maybe i suppose to add IppeerCommon which i do not have Edited October 19, 2020 by limelect Share this post Link to post
Lars Fosdal 1792 Posted October 19, 2020 Is https://limelect.com the URL you tried? The URL you use, must be the webhook URL you have configured in your Teams channel. In your MS Teams team, select the desired channel, and click on Connectors from the ••• menu. In that channel you must define an Incoming Webhook. Share this post Link to post
limelect 48 Posted October 19, 2020 Yes but the problem is not the URL!! this just to put something. The problem is much before that FClient := TRESTClient.Create(nil); Share this post Link to post
Uwe Raabe 2057 Posted October 19, 2020 The Delphi 10.2 implementation of TRESTClient still makes use of the IPPeerAPI. This has been removed later in 10.3. Share this post Link to post
limelect 48 Posted October 19, 2020 @uwe Raabe I tried to add IppeerCommon as the error suggested and it does not exist. Share this post Link to post
Lars Fosdal 1792 Posted October 19, 2020 Googled a bit: https://stackoverflow.com/questions/42096402/eipabstracterror-while-creating-delphi-trestclient Share this post Link to post
limelect 48 Posted October 19, 2020 @lars this is the first thing I did. GOOGLE GOOGLE GOOGLE! To the point, I do not have the Delphi version needed. What I have is a Professional ver. Never needed above it. Share this post Link to post
Rollo62 536 Posted October 19, 2020 2 minutes ago, limelect said: GOOGLE GOOGLE GOOGLE! <OT> Have I ever noticed how silly "BING BING BING !" would sound </OT> 1 Share this post Link to post