Help with Teams notification

I have attempted to set up a button in Ignition to test out sending a message to MS Teams. I followed the example here Sending Ignition notifications to Microsoft Teams. I am not a programmer, so I got stuck at the part where it says "application/json". I'm not sure what to put here. I tried the code just as the author of the article stated, but I put in my own url for the webhook. I am getting a Parse error on the below line.

system.net.httpPost(uri, “application/json”, message, 10000, 60000)

It states that there is "no viable alternative at character '?'" around the application/json term. I'm sure that I have to replace "application/json" with something meaningful, but I have no idea what that is suppposed to be. Any help on this would be appreciated!

Those are curly quotes, not normal double quotes. Python doesn't understand them. Typically caused by copying from code on this forum that isn't marked as such (using the "preformatted text" button in the comment editor). This forum, like most others, assumes pasted text is simple prose, and tries to make it "pretty". That is catastrophic for code punctuation and indentation.

Thank you Phil--I replaced them with regular quote marks, but am now getting a "IOError: Server returned HTTP response code: 400 for URL:" (and then the webhook is here). I checked the webhook several times, and it is correct.

That article explains some of the possible causes for error 400. You know as much as I at this point. (Is that error response accompanied by any explanatory detail in the response body?)

Just the below, but that doesn't tell me anything! I've asked our IT dept to look at it.

Traceback (most recent call last):
File "event:actionPerformed", line 5, in
IOError: Server returned HTTP response code: 400 for URL: https://xxxxxxxxxxxxxxxxxx (not actual webhook)

at org.python.core.Py.fromIOException(Py.java:216)
at org.python.core.Py.IOError(Py.java:183)
at com.inductiveautomation.ignition.common.script.builtin.AbstractNetUtilities.httpPost(AbstractNetUtilities.java:359)
at com.inductiveautomation.ignition.common.script.builtin.AbstractNetUtilities.httpPost(AbstractNetUtilities.java:326)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:552)
at org.python.core.PyObject.__call__(PyObject.java:433)
at org.python.core.PyObject.__call__(PyObject.java:437)
at org.python.pycode._pyx23.f$0(<event:actionPerformed>:5)
at org.python.pycode._pyx23.call_function(<event:actionPerformed>)
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1687)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:803)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:206)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:299)
at com.inductiveautomation.factorypmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:57)
at com.sun.proxy.$Proxy60.actionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.desktop/java.awt.Component.processEvent(Unknown Source)
at java.desktop/java.awt.Container.processEvent(Unknown Source)
at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at com.inductiveautomation.snap.swing.RibsEventQueue.dispatchEvent(RibsEventQueue.java:99)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)

Ignition v8.1.22 (b2022110109)
Java: Azul Systems, Inc. 11.0.16.1

Don't use httpPost. It is legacy code. Try again with httpClient.

I tried httpClient and got a different error msg. this time:

Traceback (most recent call last):
File "event:actionPerformed", line 5, in
TypeError: httpClient(): argument timeout: expected Long instance, got PyString

at org.python.core.Py.TypeError(Py.java:236)
at com.inductiveautomation.ignition.common.script.PyArgParser$PyArgument.validate(PyArgParser.java:620)
at com.inductiveautomation.ignition.common.script.PyArgParser.getTyped(PyArgParser.java:172)
at com.inductiveautomation.ignition.common.script.PyArgParser.getLong(PyArgParser.java:307)
at com.inductiveautomation.ignition.common.script.builtin.AbstractNetUtilities.httpClient(AbstractNetUtilities.java:513)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:549)
at org.python.core.PyObject.__call__(PyObject.java:433)
at org.python.core.PyObject.__call__(PyObject.java:437)
at org.python.pycode._pyx25.f$0(<event:actionPerformed>:5)
at org.python.pycode._pyx25.call_function(<event:actionPerformed>)
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1687)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:800)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:206)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:299)
at com.inductiveautomation.factorypmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:57)
at com.sun.proxy.$Proxy59.actionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.desktop/java.awt.Component.processEvent(Unknown Source)
at java.desktop/java.awt.Container.processEvent(Unknown Source)
at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)

Ignition v8.1.21 (b2022092908)
Java: Azul Systems, Inc. 11.0.15

You're going to have to show your code. Sanitize for secrets, of course.

Gladly! FYI, I tried the httpClient, and that didn't work either. I appreciate your attention on this--thank you very much. Is it possible that a firewall is in place that is causing the 400 error? I looked at the article again to see what could cause it, and nothing stood out to me.

message = "Test Alert from Ignition SCADA"

uri = "https://teknovaus.webhook.office.com/(remainder of webhook here)

system.net.httpPost(uri, "application/json", message, 10000, 60000)


Just a heads up incase someone else figured it out, I think this works great for pushing a message to a group, but I have never managed to figure out how to target an individual user with a message. That would be ideal because then you could treat it like traditional SMS notification with a schedule

Well, the "remainder of the webhook" is almost certainly the problem. According to the article, a 400 error code implies that the hook is working, but the information supplied is incomplete. That wouldn't be a firewall problem, I wouldn't think.

{ Please also use the "pre-formatted text" button when pasting code or logged errors. }